JAVA 8
Features and other cool stuff
A bit of history
● (“1.0”) -> LocalDate.of(1996, Month.JANUARY, 23)
● (“1.1”) -> LocalDate.of(1997, Month.FEBRUARY, 19)
● (“1.2”) -> LocalDate.of(1998, Month.DECEMBER, 9)
● (“1.3”) -> LocalDate.of(2000, Month.MAY, 8)
● (“1.4”) -> LocalDate.of(2002, Month.FEBRUARY, 6)
● (“1.5”) -> LocalDate.of(2004, Month.SEPTEMBER, 30)
● (“1.6”) -> LocalDate.of(2006, Month.DECEMBER, 11)
● (“1.7”) -> LocalDate.of(2011, Month.JULY, 7)
● (“1.8”) -> LocalDate.of(2014, Month.MARCH, 15)
JAVA 8, what more ?
● JAVA 8 is for JAVA 7 what JAVA 5 was for JAVA 1.4
● Lot’s of cool stuff
● Finally fonctional programming oriented
● With great power comes great responsability
● Ok, let’s dive into
Lambdas : let’s blow your mind
Lambdas : let’s blow your mind
Arrays.asList( "a", "b", "d" ).forEach( ( String e ) -> System.out.println( e ));
Arrays.asList( "a", "b", "d" ).forEach( e -> {
System.out.print( e );
System.out.print( e );
} );
Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );
Lambdas : some explanations
● Anonymous method
● To unlearn what you’ve learned, you have to
● (argtype arg...) -> { return some expression.. probably using these arguments }
● Type inference : JVM compiler guess for you args types
● Welcome to functional programming !
Functional interfaces : let’s be friends
Functional interfaces : let’s be friends
● Interfaces with only ONE abstract method
● Can contains static and default method (next slide, don’t panic)
● Most of generic functional use case already in java.util.function package
○ Function, Supplier, Consumer, Predicate, etc.
● The backbone of lambda
@FunctionalInterface
public interface Functional {
void method();
}
Interface’s Default/Static Methods
Interface’s Default Methods : abstract death ?
● Not required to be implemented
● Inherited by default
● Overridden allowed
● Public visibility only
Interface’s Default Methods : abstract death ?
private interface Defaulable {
// Interfaces now allow default methods, the implementer may or
// may not implement (override) them.
default String notRequired() {
return "Default implementation";
}
}
private static class DefaultableImpl implements Defaulable {
}
private static class OverridableImpl implements Defaulable {
@Override
public String notRequired() {
return "Overridden implementation";
}
}
Interface’s Static Methods : tooling in interface
● Act as static class method
● An interface can now contain all the tooling
private interface DefaulableFactory {
// Interfaces now allow static methods
static Defaulable create( Supplier< Defaulable > supplier ) {
return supplier.get();
}
}
Method References : let’s take some shortcuts
Method References : let’s take some shortcuts
● Another way, more concise, to refer directly to existing methods
● Constructor reference
● Static method reference
● Instance method reference
● Instance method reference using Class
Method reference : example please !
public class Example {
public int add(int a, int b) {
return a + b;
}
public static int mul(int a, int b) {
return a * b;
}
public String lower(String a) {
return a.toLowerCase();
}
public void printDate(Date date) {
System.out.println(date);
}
public void oper(IntBinaryOperator operator, int a, int b) {
System.out.println(operator.applyAsInt(a, b));
}
public void operS(Function<String, String> stringOperator, String a) {
System.out.println(stringOperator.apply(a));
}
public GregorianCalendar operC(Supplier<GregorianCalendar> supplier) {
return supplier.get();
}
}
Constructor reference
ex.operC(()->{ return new GregorianCalendar();})
ex.operC(GregorianCalendar::new);
● Lambda way
● Method reference way
Static method reference
● Lambda way
● Method reference way
ex.oper((a, b) -> Example.mul(a, b), 1, 2);
ex.oper(Example::mul, 1, 2);
Instance method reference
● Lambda way
● Method reference way
ex.oper((a, b) -> ex.add(a, b), 1, 2);
ex.oper(ex::add, 1, 2);
Instance method reference using class
● Lambda way
● Method reference way
ex.operS(String::toLowerCase, "STRING");
ex.operS(s->s.toLowerCase(), "STRING");
Method References : WARNING !!!
Should be assignable to a functionnal interface
Repeating annotations : hide me this
Repeating annotations : hide me this
● Same annotation can be repeat several times
● How to
@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { ... }
@Repeatable(Schedules.class)
public @interface Schedule {
String dayOfMonth() default "first";
String dayOfWeek() default "Mon";
int hour() default 12;
}
public @interface Schedules {
Schedule[] value();
}
Extended Annotations Support : annotation everywhere !
Extended Annotations Support : annotation everywhere !
● ElementType.TYPE_USE -> Annotation on type use
● ElementType.TYPE_PARAMETER -> Annotation on type variable
@NonNull String name; // Type use
List<@NonNull String> names; // Type parameter
class UnmodifiableList<T> implements @Readonly List<@Readonly T>
{...}
email = (@Email String) input;
new @Information MyObject();
void doSomething() throws @ImportantForMe MyException { ... }
Parameter names : for reflection lovers only
Parameter names : for introspection lovers only
JVM arg : -parameter
Optional is not an option : end of NullPointer ?
Optional< String > fullName = Optional.ofNullable( null );
System.out.println( "Full Name is set? " + fullName.isPresent() );
System.out.println( "Full Name: " + fullName.orElseGet( () -> "[none]" ) );
System.out.println( fullName.map( s -> "Hey " + s + "!" ).orElse( "Hey Stranger!" ) );
Full Name is set? false
Full Name: [none]
Hey Stranger!
Optional is not an option : end of NullPointer ?
Optional< String > firstName = Optional.of( "Tom" );
System.out.println( "First Name is set? " + firstName.isPresent() );
System.out.println( "First Name: " + firstName.orElseGet( () -> "[none]" ) );
System.out.println( firstName.map( s -> "Hey " + s + "!" ).orElse( "Hey Stranger!" ) );
First Name is set? true
First Name: Tom
Hey Tom!
Optional is not an option : end of NullPointer ?
Streams : THIS IS map/reduce !!!
● Create a pipeline made of operations
● Terminal operation could produce another data store
● Parallelization
Streams : THIS IS map/reduce !!!
final Collection< Task > tasks = Arrays.asList(
new Task( Status.OPEN, 5 ),
new Task( Status.OPEN, 13 ),
new Task( Status.CLOSED, 8 )
);
// Calculate total points of all active tasks using sum()
final long totalPointsOfOpenTasks = tasks
.stream()
.filter( task -> task.getStatus() == Status.OPEN )
.mapToInt( Task::getPoints )
.sum();
System.out.println( "Total points: " + totalPointsOfOpenTasks );
Total points: 18
Streams : THIS IS map/reduce !!!
final Collection< Task > tasks = Arrays.asList(
new Task( Status.OPEN, 5 ),
new Task( Status.OPEN, 13 ),
new Task( Status.CLOSED, 8 )
);
// Group tasks by their status
final Map< Status, List< Task > > map = tasks
.stream()
.collect( Collectors.groupingBy( Task::getStatus ) );
System.out.println( map );
{CLOSED=[[CLOSED, 8]], OPEN=[[OPEN, 5], [OPEN, 13]]}
Streams : THIS IS map/reduce !!!
final Collection< Task > tasks = Arrays.asList(
new Task( Status.OPEN, 5 ),
new Task( Status.OPEN, 13 ),
new Task( Status.CLOSED, 8 )
);
// 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 );
[19%, 50%, 30%]
Streams : THIS IS map/reduce !!!
Date/Time API : Joda time was here...
● Inspired by JODA Time : made by developpers for developpers
● One package : java.time
● IMMUTABLE by design
Date/Time API : Joda time was here...
Date/Time API : Clock
// Get the system clock as UTC offset
final Clock clock = Clock.systemUTC();
System.out.println( clock.instant() );
System.out.println( clock.millis() );
2014-04-12T15:19:29.282Z
1397315969360
Date/Time API : LocalDate / LocalTime
// Get the local date and local time
final LocalDate date = LocalDate.now();
final LocalDate dateFromClock = LocalDate.now( clock );
System.out.println( date );
System.out.println( dateFromClock );
// Get the local date and local time
final LocalTime time = LocalTime.now();
final LocalTime timeFromClock = LocalTime.now( clock );
System.out.println( time );
System.out.println( timeFromClock );
2014-04-12
2014-04-12
11:25:54.568
15:25:54.568
Date/Time API : ZoneDateTime
// Get the zoned date/time
final Clock clock = Clock.systemUTC();
final ZonedDateTime zonedDatetime = ZonedDateTime.now();
final ZonedDateTime zonedDatetimeFromClock =
ZonedDateTime.now( clock );
final ZonedDateTime zonedDatetimeFromZone =
ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) );
System.out.println( zonedDatetime );
System.out.println( zonedDatetimeFromClock );
System.out.println( zonedDatetimeFromZone );
2014-04-12T11:47:01.017-04:00
[America/New_York]
2014-04-12T15:47:01.017Z
2014-04-12T08:47:01.017-07:00
[America/Los_Angeles]
Date/Time API : Duration
// Get duration between two dates
final LocalDateTime from =
LocalDateTime.of( 2014, Month.APRIL, 16, 0, 0, 0 );
final LocalDateTime to =
LocalDateTime.of( 2015, Month.APRIL, 16, 23, 59, 59 );
final Duration duration = Duration.between( from, to );
System.out.println( "Duration in days: " + duration.toDays() );
System.out.println( "Duration in hours: " + duration.toHours() );
Duration in days: 365
Duration in hours: 8783
And so many other things
And so many other things
● Nashorn JavaScript Engine : evaluate JavaScript in JAVA
● Base64 standard support
○ URL-friendly encoder/decoder
○ MIME-friendly encoder/decoder
● Parallel Arrays
● Class dependency analyzer : jdeps
● XX:PermSize / XX:MaxPermSize respectivly replaced by XX:MetaSpaceSize
/ XX:MaxMetaSpaceSize
● String.join() / Objects.nonNull()
● Reflection api support TypeName, GenericString, access Generic type, etc.
● ...
Java 8
Java 8

Java 8

  • 1.
    JAVA 8 Features andother cool stuff
  • 2.
    A bit ofhistory ● (“1.0”) -> LocalDate.of(1996, Month.JANUARY, 23) ● (“1.1”) -> LocalDate.of(1997, Month.FEBRUARY, 19) ● (“1.2”) -> LocalDate.of(1998, Month.DECEMBER, 9) ● (“1.3”) -> LocalDate.of(2000, Month.MAY, 8) ● (“1.4”) -> LocalDate.of(2002, Month.FEBRUARY, 6) ● (“1.5”) -> LocalDate.of(2004, Month.SEPTEMBER, 30) ● (“1.6”) -> LocalDate.of(2006, Month.DECEMBER, 11) ● (“1.7”) -> LocalDate.of(2011, Month.JULY, 7) ● (“1.8”) -> LocalDate.of(2014, Month.MARCH, 15)
  • 3.
    JAVA 8, whatmore ? ● JAVA 8 is for JAVA 7 what JAVA 5 was for JAVA 1.4 ● Lot’s of cool stuff ● Finally fonctional programming oriented ● With great power comes great responsability ● Ok, let’s dive into
  • 4.
    Lambdas : let’sblow your mind
  • 5.
    Lambdas : let’sblow your mind Arrays.asList( "a", "b", "d" ).forEach( ( String e ) -> System.out.println( e )); Arrays.asList( "a", "b", "d" ).forEach( e -> { System.out.print( e ); System.out.print( e ); } ); Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );
  • 6.
    Lambdas : someexplanations ● Anonymous method ● To unlearn what you’ve learned, you have to ● (argtype arg...) -> { return some expression.. probably using these arguments } ● Type inference : JVM compiler guess for you args types ● Welcome to functional programming !
  • 7.
    Functional interfaces :let’s be friends
  • 8.
    Functional interfaces :let’s be friends ● Interfaces with only ONE abstract method ● Can contains static and default method (next slide, don’t panic) ● Most of generic functional use case already in java.util.function package ○ Function, Supplier, Consumer, Predicate, etc. ● The backbone of lambda @FunctionalInterface public interface Functional { void method(); }
  • 9.
  • 10.
    Interface’s Default Methods: abstract death ? ● Not required to be implemented ● Inherited by default ● Overridden allowed ● Public visibility only
  • 11.
    Interface’s Default Methods: abstract death ? private interface Defaulable { // Interfaces now allow default methods, the implementer may or // may not implement (override) them. default String notRequired() { return "Default implementation"; } } private static class DefaultableImpl implements Defaulable { } private static class OverridableImpl implements Defaulable { @Override public String notRequired() { return "Overridden implementation"; } }
  • 12.
    Interface’s Static Methods: tooling in interface ● Act as static class method ● An interface can now contain all the tooling private interface DefaulableFactory { // Interfaces now allow static methods static Defaulable create( Supplier< Defaulable > supplier ) { return supplier.get(); } }
  • 13.
    Method References :let’s take some shortcuts
  • 14.
    Method References :let’s take some shortcuts ● Another way, more concise, to refer directly to existing methods ● Constructor reference ● Static method reference ● Instance method reference ● Instance method reference using Class
  • 15.
    Method reference :example please ! public class Example { public int add(int a, int b) { return a + b; } public static int mul(int a, int b) { return a * b; } public String lower(String a) { return a.toLowerCase(); } public void printDate(Date date) { System.out.println(date); } public void oper(IntBinaryOperator operator, int a, int b) { System.out.println(operator.applyAsInt(a, b)); } public void operS(Function<String, String> stringOperator, String a) { System.out.println(stringOperator.apply(a)); } public GregorianCalendar operC(Supplier<GregorianCalendar> supplier) { return supplier.get(); } }
  • 16.
    Constructor reference ex.operC(()->{ returnnew GregorianCalendar();}) ex.operC(GregorianCalendar::new); ● Lambda way ● Method reference way
  • 17.
    Static method reference ●Lambda way ● Method reference way ex.oper((a, b) -> Example.mul(a, b), 1, 2); ex.oper(Example::mul, 1, 2);
  • 18.
    Instance method reference ●Lambda way ● Method reference way ex.oper((a, b) -> ex.add(a, b), 1, 2); ex.oper(ex::add, 1, 2);
  • 19.
    Instance method referenceusing class ● Lambda way ● Method reference way ex.operS(String::toLowerCase, "STRING"); ex.operS(s->s.toLowerCase(), "STRING");
  • 20.
    Method References :WARNING !!! Should be assignable to a functionnal interface
  • 21.
  • 22.
    Repeating annotations :hide me this ● Same annotation can be repeat several times ● How to @Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri", hour="23") public void doPeriodicCleanup() { ... } @Repeatable(Schedules.class) public @interface Schedule { String dayOfMonth() default "first"; String dayOfWeek() default "Mon"; int hour() default 12; } public @interface Schedules { Schedule[] value(); }
  • 23.
    Extended Annotations Support: annotation everywhere !
  • 24.
    Extended Annotations Support: annotation everywhere ! ● ElementType.TYPE_USE -> Annotation on type use ● ElementType.TYPE_PARAMETER -> Annotation on type variable @NonNull String name; // Type use List<@NonNull String> names; // Type parameter class UnmodifiableList<T> implements @Readonly List<@Readonly T> {...} email = (@Email String) input; new @Information MyObject(); void doSomething() throws @ImportantForMe MyException { ... }
  • 25.
    Parameter names :for reflection lovers only
  • 26.
    Parameter names :for introspection lovers only JVM arg : -parameter
  • 27.
    Optional is notan option : end of NullPointer ?
  • 28.
    Optional< String >fullName = Optional.ofNullable( null ); System.out.println( "Full Name is set? " + fullName.isPresent() ); System.out.println( "Full Name: " + fullName.orElseGet( () -> "[none]" ) ); System.out.println( fullName.map( s -> "Hey " + s + "!" ).orElse( "Hey Stranger!" ) ); Full Name is set? false Full Name: [none] Hey Stranger! Optional is not an option : end of NullPointer ?
  • 29.
    Optional< String >firstName = Optional.of( "Tom" ); System.out.println( "First Name is set? " + firstName.isPresent() ); System.out.println( "First Name: " + firstName.orElseGet( () -> "[none]" ) ); System.out.println( firstName.map( s -> "Hey " + s + "!" ).orElse( "Hey Stranger!" ) ); First Name is set? true First Name: Tom Hey Tom! Optional is not an option : end of NullPointer ?
  • 30.
    Streams : THISIS map/reduce !!!
  • 31.
    ● Create apipeline made of operations ● Terminal operation could produce another data store ● Parallelization Streams : THIS IS map/reduce !!!
  • 32.
    final Collection< Task> tasks = Arrays.asList( new Task( Status.OPEN, 5 ), new Task( Status.OPEN, 13 ), new Task( Status.CLOSED, 8 ) ); // Calculate total points of all active tasks using sum() final long totalPointsOfOpenTasks = tasks .stream() .filter( task -> task.getStatus() == Status.OPEN ) .mapToInt( Task::getPoints ) .sum(); System.out.println( "Total points: " + totalPointsOfOpenTasks ); Total points: 18 Streams : THIS IS map/reduce !!!
  • 33.
    final Collection< Task> tasks = Arrays.asList( new Task( Status.OPEN, 5 ), new Task( Status.OPEN, 13 ), new Task( Status.CLOSED, 8 ) ); // Group tasks by their status final Map< Status, List< Task > > map = tasks .stream() .collect( Collectors.groupingBy( Task::getStatus ) ); System.out.println( map ); {CLOSED=[[CLOSED, 8]], OPEN=[[OPEN, 5], [OPEN, 13]]} Streams : THIS IS map/reduce !!!
  • 34.
    final Collection< Task> tasks = Arrays.asList( new Task( Status.OPEN, 5 ), new Task( Status.OPEN, 13 ), new Task( Status.CLOSED, 8 ) ); // 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 ); [19%, 50%, 30%] Streams : THIS IS map/reduce !!!
  • 35.
    Date/Time API :Joda time was here...
  • 36.
    ● Inspired byJODA Time : made by developpers for developpers ● One package : java.time ● IMMUTABLE by design Date/Time API : Joda time was here...
  • 37.
    Date/Time API :Clock // Get the system clock as UTC offset final Clock clock = Clock.systemUTC(); System.out.println( clock.instant() ); System.out.println( clock.millis() ); 2014-04-12T15:19:29.282Z 1397315969360
  • 38.
    Date/Time API :LocalDate / LocalTime // Get the local date and local time final LocalDate date = LocalDate.now(); final LocalDate dateFromClock = LocalDate.now( clock ); System.out.println( date ); System.out.println( dateFromClock ); // Get the local date and local time final LocalTime time = LocalTime.now(); final LocalTime timeFromClock = LocalTime.now( clock ); System.out.println( time ); System.out.println( timeFromClock ); 2014-04-12 2014-04-12 11:25:54.568 15:25:54.568
  • 39.
    Date/Time API :ZoneDateTime // Get the zoned date/time final Clock clock = Clock.systemUTC(); final ZonedDateTime zonedDatetime = ZonedDateTime.now(); final ZonedDateTime zonedDatetimeFromClock = ZonedDateTime.now( clock ); final ZonedDateTime zonedDatetimeFromZone = ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ); System.out.println( zonedDatetime ); System.out.println( zonedDatetimeFromClock ); System.out.println( zonedDatetimeFromZone ); 2014-04-12T11:47:01.017-04:00 [America/New_York] 2014-04-12T15:47:01.017Z 2014-04-12T08:47:01.017-07:00 [America/Los_Angeles]
  • 40.
    Date/Time API :Duration // Get duration between two dates final LocalDateTime from = LocalDateTime.of( 2014, Month.APRIL, 16, 0, 0, 0 ); final LocalDateTime to = LocalDateTime.of( 2015, Month.APRIL, 16, 23, 59, 59 ); final Duration duration = Duration.between( from, to ); System.out.println( "Duration in days: " + duration.toDays() ); System.out.println( "Duration in hours: " + duration.toHours() ); Duration in days: 365 Duration in hours: 8783
  • 41.
    And so manyother things
  • 42.
    And so manyother things ● Nashorn JavaScript Engine : evaluate JavaScript in JAVA ● Base64 standard support ○ URL-friendly encoder/decoder ○ MIME-friendly encoder/decoder ● Parallel Arrays ● Class dependency analyzer : jdeps ● XX:PermSize / XX:MaxPermSize respectivly replaced by XX:MetaSpaceSize / XX:MaxMetaSpaceSize ● String.join() / Objects.nonNull() ● Reflection api support TypeName, GenericString, access Generic type, etc. ● ...