Java 7 & Java 8 changes

Java 7

Binary Literals:

  • int[] array = { 0b1111, 0b0000 };

Type Inference:

  • Map<String, String> map = new HashMap<>();

Underscores:

  • double pi = 3.14159_26535;
  • long lightyear = 9_460_730_472_580_800;
  • long header = 0xCAFE_BABE;

String switch:

  • switch(str) {
      case "key1": return 1;
      case "key2": return 2;
      default: throw new NotFoundException();
    }

try-with-resources:

  • try (FileReader fr = new FileReader(fileName); BufferedReader br = new BufferedReader(fr);) {
      br.readLine();
    }

Catching multiple exception types:

  • try {
      method.invoke(object, new Object[] {});
    } catch (IllegalArgumentException | NullPointerException ex) {
      logger.warn("Failed!", ex);
    }

Rethrowing Exceptions with type checking:

  • void method() throws Exception1, Exception2 {
      try {
        if (error1) throw new Exception1();
        if (error2) throw new Exception2();
      } catch (Exception e) {
        throw e;
      }
    }

 

Java 8

Lambdas (Closures):

  • Arrays.asList("a", "b", "c").forEach( e -> System.out.println( e ) );
  • Arrays.asList("a", "b", "c").forEach( (String e) -> {
      System.out.println( e );
      System.out.println( e );
    } );
  • Arrays.asList("a", "b", "c").sort( ( e1, e2) -> e1.compareTo( e2 ) );
  • Arrays.asList("a", "b", "c").sort( ( e1, e2) -> {
      int result = e1.compareTo( e2 );
      return result;
    } );

Functional Interfaces:

  • @FunctionalInterface
    public interface Function1 {
      void method();
    }

Default methods in interfaces:

  • public interface Defaultable {
      default String notRequired() {
        return "default implementation";
      }
    }

Static methods in interfaces:

  • public interface DefaultableFactory {
      // declares and provides implementation of static methods
      static Defaulable create( Supplier< Defaulable > supplier) {
        return supplier.get();
      }
    }
    
    public static void main(String... args) {
      Defaulable obj = DefaulableFactory.create( DefaultableImpl::new );
    }
    

Method References:

  • public static class Car {
      // constructor reference with the syntax Class::new or Class< T > ::new
      public static Car create( final Supplier< Car > supplier ) {
        return supplier.get();
      }
      
      // reference to static method with the syntax Class::static_method
      public static void collide( final Car car ) { ... }
    
      // reference to instance method of arbitrary object of specific type with the syntax Class::method
      public static void repair( ) { ... }
    
      // reference to instance method of particular class instance with the syntax instance::method
      public void follow( final Car another ) { ... }
    }
    
    public static void main(String... args) {
      final Car car = Car.create( Car::new );
      final List< Car > cars = Arrays.asList( car);
    
      cars.forEach( Car::collide );
    
      cars.forEach( Car::repair );
    
      final Car police = Car.create( Car::new );
      cars.forEach( police::follow );  
    }

Repeating annotations:

  • @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Filters {
      Filter[] value();
    }
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(Filters.class)
    public @interface Filter {
      String value();
    }
    
    @Filter("filter1")
    @Filter("filter2")
    public interface Filterable {
    }
    
    public static void main(String... args) {
      for( Filter filter: Filterable.class.getAnnotationsByType( Filter.class )) {
        System.out.println( filter.value() );
      }
    }

Better Type Inference:

  • public class Value< T > {
      public static< T > T defaultValue() { return null; }
      public T getOrDefault( T value, T defaultValue ) { return ...; }
    }
    
    public static void main(String... args) {
      final Value< String > value = new Value<>();
      value.getOrDefault("2", Value.defaultValue() );
    }

Extended Annotations Support:

  • local variables
  • generic types
  • super-classes
  • implementing interfaces
  • exception declarations

Optional:

  • Optional<String> name = Optional.ofNullable( null );
  • name.isPresent(); // false
  • name.orElseGet( () > "none" )); // none
  • name.map( s > "Hi "+s).orElse("Hi!")); // Hi!

Stream API:

  • final Collection< Task > tasks = Arrays.asList( new Task(Tastus.OPEN, 5), ... );
  • final long totalPointsOfOpenTasks = tasks.stream()
      // filters out all NON-OPEN tasks
      .filter( task > task.getStatus() == Status.OPEN )
      // converts the stream to the stream of Integers
      .mapToInt( Task:.getPoints )
      .sum();
  • final double totalPoints = tasks.stream()
      // process all tasks in parallel
      .parallel()
      // converts the stream to the stream of Integers
      .map( task > task.getPoints() )
      // calculate the final result using reduce method
      .reduce( 0, Integer::sum );
  • final Map<Status, List<Task>> map = tasks.stream()
      // group tasks by their status
      .collect( Collectors.groupingBy( Task::getStatus());
  • final Path path = new File(filename).toPath();
    try (Stream< String> lines = Files.lines( path, StandardCharsets.UTF_8 )) {
      lines.onClose( () > System.out.println("Done!")).forEatch(System.out.println);
    }

 Date/Time API:

  • Clock clock = Clock.systemUTC();
  • LocalDate date = LocalDate.now();
  • LocalTime time = LocalTime.now();
  • LocalDateTime datetime = LocalDateTime.now();
  • ZonedDateTime zonedDatetime = ZonedDateTime.now( ZoneId.of("America/Los_Angeles") );
  • Duration duration = Duration.between( from, to);

Nashorn JavaScript engine:

  • (new ScriptEngineManager()).getEngineByName("JavaScript").eval("function f() { return 1; }; f() + 1;"); // result: 2
  • command line: “jjs func.js”

Base64:

  • String encoded = Base64.getEncoder().encodeToString( str.getBytes( StandardCharsets.UTF_8 ));
  • String decoded = new String( Base64.getDecoder().decode( encoded), StandardCharsets.UTF_8 )
  • // Base64.getMimeEncoder()
  • // Base64.getMimeDecoder()
  • // Base64.getUrlEncoder()
  • // Base64.getUrlDecoder()

Parallel Arrays:

  • Arrays.parallelSetAll( array, index > ThreadLocalRandom.current().nextInt( 100000) );
  • Arrays.parallelSort( array );
  • Arrays.stream( array ).limit( 10).forEach( i > System.out.print(i + " "));

JVM Metaspace:

  • // replaces PermGen
  • -XX:MetaSpaceSize -XX:MaxMetaspaceSize
Advertisements