Java 8
The good parts

Writing Java has never been so fun

@bentolor

Table of contents

Usage hint: Use mouse scoll or cursor right & down to navigate!

Java 8 is big

Language
  • Lambdas & Functional Interfaces
  • Method References
  • Default Methods
  • Better annotations
  • Better Type Inference

Java 8 is big

Runtime library
  • Streams
  • Optional
  • Multicore Support (Parallel)
  • Native Javascript
  • Many Goodies

Java 8 is big

Compiler & Tools
  • Reflection: Parameter names
  • CLI: jjs (Nashorn)
  • CLI: jdeps
  • Death of PermGen

Language changes

Lambdas

Basic form

(params) -> expression
(params) -> statement
(params) -> { statements }

A simple example (no parameters):

Runnable r = () -> System.out.println("Hello!");
r.run();

Example with parameter (Type inferred!)

Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );

Lambdas

Lambdas can access outer field / variables if they are (effectively) final

String separator = ",";
Arrays.asList( "a", "b", "d" )
    .forEach( (String e) -> System.out.print(e+separator) );

//separator = ";"   // would break!

Lambdas may return values (inline/explicit)

Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> e1.compareTo( e2 ) );

// or:
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> {
    return e1.compareTo( e2 );
} );        

Functional interfaces

Comparator <Apple> c =
     (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
Wait, wait, wait... Comparator? How does this work?
@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
}

@FunctionalInterface

Conceptually, a functional interface has exactly one abstract method. As such, it may be implicitly converted to a lambda expression.

Note that instances of functional interfaces can be created with lambda expressions or method/constructor references.

But: To avoid breakage by accidently adding further methods , these interfaces should be explicitly tagged with @FunctionalInterface.

Interface default methods

In Java 8 you can write:

List<Integer> numbers = Arrays.asList(3, 5, 1, 2, 6);
numbers.sort(Comparator.naturalOrder());

Huh? java..util.List now requires a sort()-Method?
Will all of my code break now?

public interface List<E> extends Collection<E> {
    // ...
    default void sort(Comparator<? super E> c) {
        // ...
    }
}

Interface static methods

private interface PersonFactory {
    // Interfaces now allow static methods
    static Person createPerson( String firstname, String lastname ) {
        return new Person(firstname, lastname);
    }
}

Method references

Given the following interface

public interface MyFormatter<T> {
    String format(T object);
}

public <T> String format(T o,  MyFormatter<T> formatter) {
    return formatter.format(o);
}

We can simply reuse existing other implementations

format(32, Integer::toHexString)

Supported method references

  • static method: Class::staticMethodName
  • instance method of a particular object object::methodName
  • instance method of an arbitrary object Type::methodName
  • constructor: ClassName::new

Runtime library enhancement

Streams

Collection<Task> tasks = getTasks();
long totalPointsOfOpenTasks = tasks
    .stream()
    .filter( task -> task.getStatus() == Status.OPEN )
    .mapToInt( Task::getPoints )
    .sum();

System.out.println( "Total points: " + totalPointsOfOpenTasks );

Stream operations

Are divided into

  • Intermediate operations (returning another Stream<T>)
  • Terminal operations (returning the final result)

Parallel processing

Out-of-the box support of parallel processing (Multi-threading!)

stream.parallel()

Complex stream example

// Calculate the weight of each tasks (as percent of total points)
final Collection<String> result = tasks
        .stream()                                        // Stream<String>
        .mapToInt( Task::getPoints )                     // IntStream
        .asLongStream()                                  // LongStream
        .mapToDouble( points -> points / totalPoints )   // DoubleStream
        .boxed()                                         // Stream<Double>
        .mapToLong( weigth -> ( long )( weigth * 100 ) ) // LongStream
        .mapToObj( percentage -> percentage + "%" )      // Stream<String>
        .collect( Collectors.toList() );                 // List<String>

System.out.println( result );

Optional

Allows you to commit to a non-null convention in your project
& offers some convenience.

Optional<String> fullName = Optional.ofNullable( null );
log.info( "Full Name is set? " + fullName.isPresent() );
log.info( "Full Name: " + fullName.orElseGet( () -> "[none]" ) );
log.info( fullName.map( s -> "Hey " + s + "!" ).orElse( "Hey Stranger!" ) );

No more NullPointerException?

Native Javascript Support (Nashorn)

Use / Run Javascript in your code:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName( "JavaScript" );

System.out.println( engine.eval( "function f() { return 1; }; f() + 1;" ) );
From command line
jjs server.js

Smaller goodies

Better Annotations

Repeatable
@Filter( "filter1" )
@Filter( "filter2" )
public interface Filterable { }
... assigned to variables, constructors, maps, casts, ...
@NotNull String myString = "Foo"
new @Interned MyObject()
myString = (@NonNull String) myObject;
... used in Generics
List<@Email String> emails = ...
... and more!

Better type inference

Parameter names

Method method = ParameterNames.class.getMethod( "main", String[].class );
for( final Parameter parameter: method.getParameters() ) {
  System.out.println( "Parameter: " + parameter.getName() );
}

Date/Time API (JSR 310)

  • More convenience & easier operations.
  • Time-zone less data types (i.e. LocalDate)

java.util.Base64

Better Multithreading support

  • list.parallelStream()
  • stream.parallel()
  • ConcurrentMap.parallelStream()
  • Arrays.parallelSort()
  • Arrays.parallelSetAll()

Small enhancements in java.util.concurrent

Tools & JVM

jdeps

Class dependency analyzer

$ jdeps org.springframework.core-3.0.5.jar
org.springframework.core-3.0.5.jar -> lib\rt.jar
   org.springframework.core (org.springframework.core-3.0.5.jar)
      -> java.io
      -> java.lang
      -> java.lang.annotation
      -> java.lang.ref
      -> java.lang.reflect
      -> java.util
      -> java.util.concurrent
      -> org.apache.commons.logging                         not found
      -> org.springframework.asm                            not found
   org.springframework.core.annotation (org.springframework.core-3.0.5.jar)
      -> java.lang
      -> java.lang.annotation
      -> java.lang.reflect
      -> java.util

PermGen is now
MetaSpace

Resources

Thank you :)

Fork me on GitHub