Google

Apr 12, 2014

Top 8 new features in Java 7 with examples -- part 2

Extends Top 8 new features in Java 7 with examples -- part 1.


#5 Multi-catch to avoid code duplication

public class Java7Feature4 {

 public static void main(String[] args) {

  //pre Java 7
  try {
   someMethod();
  } catch (CustomException1 ex1) {
   ex1.printStackTrace();
  } catch (CustomException2 ex2) {
   ex2.printStackTrace();
  }
  
  
  //Java 7 -- 5 lines as opposed to 7 lines.
  //no code duplication
  try {
   someMethod();
  } catch (CustomException1|CustomException2 ex) {
   ex.printStackTrace();
  }
 }

 public static void someMethod() throws CustomException1, CustomException2 {

 }

 public static class CustomException1 extends Exception {
  private static final long serialVersionUID = 1L;
 }

 public static class CustomException2 extends Exception {
  private static final long serialVersionUID = 1L;
 }

}

Note that the pipe ‘|’ character is used as the delimiter.

#6 Improved type inference for generic instance creation

This is only a small change that makes generics declaration a little less verbose. As shown below, you can just use empty diamond "<>" in Java 7 on the RHS.

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Java7Feature4 {

 public static void main(String[] args) {
        //Pre Java 7
  getEmployeesWithManagersOld("a102");
  //Java 7
  getEmployeesWithManagersNew("a102");
 }

 
 public static Map<String, List<Employee>>  getEmployeesWithManagersOld(String empCode){
   if(empCode == null){
      return Collections.emptyMap();
   }
   
   //gives type safety warning. You need to add <String, List<Employee>> again on the RHS
   Map<String, List<Employee>> mapEmployees = new HashMap();
   
   
   return mapEmployees;
 }

 
 //Java 7
 public static Map<String, List<Employee>>  getEmployeesWithManagersNew(String empCode){
   if(empCode == null){
      return Collections.emptyMap();
   }
   
   //no duplication of generic inference
   Map<String, List<Employee>> mapEmployees = new HashMap<>();
   //do something with mapEmployees
   
   return mapEmployees;
 }

  
 static class Employee {}
}


#7: More new I/O APIs for the Java platform (NIO - 2.0)

Those who worked with Java IO may still remember the headaches that framework caused. It was never easy to work seamlessly across operating systems or multi-file systems. The NIO 2.0 has come forward with many enhancements. It’s also introduced new classes to ease the life of a developer when working with multiple file systems with classes and interfaces such as Path, Paths, FileSystem, FileSystems and others.

Another very handy feature is the WatchService for file change notifications. It can monitor a directory for changes as demonstrated below.

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

public class Java7Feature7 {

 public static void main(String[] args) throws IOException, InterruptedException {
  
  // Java 7
  Path path = Paths.get("c:\\Temp\\simple.txt");
  System.out.println(path.getFileName());
  System.out.println(path.getRoot());
  System.out.println(path.getParent());

  // Java 7 file change watch service
  WatchService watchService = FileSystems.getDefault().newWatchService();
  
  //register Temp folder with the watch service for addition of new file, modification of a file name, and deletion of a file
  path.getParent().register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
    StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE);

  //wait for incoming events
  while (true) {
   final WatchKey key = watchService.take();
   for (WatchEvent<?> watchEvent : key.pollEvents()) {
    final Kind<?> kind = watchEvent.kind();
    // Overflow event
    if (StandardWatchEventKinds.OVERFLOW == kind) {
     continue; // loop
    } else if (StandardWatchEventKinds.ENTRY_CREATE == kind || StandardWatchEventKinds.ENTRY_MODIFY == kind
      || StandardWatchEventKinds.ENTRY_DELETE == kind) {
     @SuppressWarnings("unchecked")
     final WatchEvent<Path> watchEventPath = (WatchEvent<Path>) watchEvent;
     final Path entry = watchEventPath.context();

     System.out.println(kind + "-->" + entry);

    }

   }

   if (!key.reset()) {
    break;
   }
  }

  // deleting a file is as easy as.
  Files.deleteIfExists(path); // Java 7 feature as well.
 }

}


The output will be something like:

simple.txt
c:\
c:\Temp
ENTRY_CREATE-->New Text Document.txt
ENTRY_DELETE-->New Text Document.txt
ENTRY_CREATE-->File1.txt
ENTRY_MODIFY-->File1.txt


#8: Fork and Join

Java 7 has incorporated the feature that would distribute the work across multiple cores and then join them to return the result set as a Fork and Join framework. he effective use of parallel cores in a Java program has always been a challenge. It’s a divide-and-conquer algorithm where Fork-Join breaks the task at hand into mini-tasks until the mini-task is simple enough that it can be solved without further breakups. One important concept to note in this framework is that ideally no worker thread is idle. They implement a work-stealing algorithm in that idle workers “steal” the work from those workers who are busy.

The example below demonstrates this with a simple task of summing up 10 numbers. If the count of numbers to be added are greater than 5, it is forked into chunks of 5 to be processed by separate thread, and the forked sum are then joined to give the overall total of 10 numbers from 1 to 10, which is 55.  The total of numbers 1 to 5 is 15, and 6 to 10 is 40.

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class Java7Feature8 {

 static int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

 public static void main(String[] args) throws IOException, InterruptedException {
     int numberOfCpuCores = Runtime.getRuntime().availableProcessors();
     ForkJoinPool forkJoinPool = new ForkJoinPool(numberOfCpuCores);
     int sum = forkJoinPool.invoke(new ChunkingTask(numbers));
     System.out.println(sum);
 }

 //inner class
 static class SumCalculatorTask extends RecursiveTask<Integer> {
  int[] numbers;

  SumCalculatorTask(int[] numbers) {
   this.numbers = numbers;
  }

  @Override
  protected Integer compute() {
   int sum = 0;
   for (int i : numbers) {
    sum += i;
   }
   
   System.out.println(Thread.currentThread().getName() + " sum = " + sum);

   return sum;
  }
 }

 
 //inner class
 
 /**
  * 
  *chunking size is 5
  */
 static class ChunkingTask extends RecursiveTask<Integer> {

  private static final int CHUNK_SIZE = 5;
  int[] numbers;

  ChunkingTask(int[] numbers) {
   this.numbers = numbers;
  }

  @Override
  protected Integer compute() {
   int sum = 0;
   List<RecursiveTask<Integer>> forks = new ArrayList<>();
   
   //if the numbers size is > CHUNK_SIZE fork them
   if (numbers.length > CHUNK_SIZE) {
    ChunkingTask chunk1 = new ChunkingTask(Arrays.copyOfRange(numbers, 0, numbers.length / 2));
    ChunkingTask chunk2 = new ChunkingTask(Arrays.copyOfRange(numbers, numbers.length / 2, numbers.length));
    forks.add(chunk1);
    forks.add(chunk2);
    chunk1.fork();
    chunk2.fork();
   //size is less than or equal to CHUNK_SIZE start summing them 
   } else {
    SumCalculatorTask sumCalculatorTask = new SumCalculatorTask(numbers);
    forks.add(sumCalculatorTask);
    sumCalculatorTask.fork();
   }

   // Combine the result from all the tasks
   //join 
   for (RecursiveTask<Integer> task : forks) {
    sum += task.join();
   }

   return sum;
  }

 }

}


Output is:

ForkJoinPool-1-worker-2 sum = 15
ForkJoinPool-1-worker-2 sum = 40
55

Java 8's Arrays.parallelSort( ... ) make use of this fork and join feature to sort an array in parallel.

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home