Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What's new in Java 8

What's new in Java 8

No doubt the biggest change in Java 8 is the addition of lambdas. But Java 8 is more than that. In this talk Bart takes you on a whirlwind tour through the most important added features and changes in Java 8.

Bart Bakker

May 15, 2014
Tweet

More Decks by Bart Bakker

Other Decks in Programming

Transcript

  1. It took 19 years of madness Calendar calendar = GregorianCalendar.getInstance();

    calendar.set(2014, 4, 15, 0, 0, 0); ! calendar.getTime(); // => Thu May 15 00:00:00 CEST 2014 ! calendar.getTime().getYear(); // => 114
  2. Joda showed the way for almost 10 years LocalDate today

    = new LocalDate(2014, 5, 15); ! today.toString("MMM dd, yyyy”); // => May 15, 2014
  3. .. to get a
 Date and Time API LocalDate today

    = LocalDate.of(2014, 5, 15); ! today.getMonth(); // => MAY ! LocalDate tomorrow = today.plusDays(1); tomorrow.getDayOfMonth(); // => 16 ! today.getDayOfMonth(); // => 15
  4. Adjusters LocalDate today = LocalDate.now(); ! today.with(firstDayOfMonth()); // => 2014-05-01

    ! today.with(lastDayOfMonth()); // => 2014-05-31 ! today.with(lastInMonth(TUESDAY)); // => 2014-05-27
  5. Timezones ZoneId amsterdam = ZoneId.of("Europe/Amsterdam"); ZoneId chicago = ZoneId.of("America/Chicago"); !

    ZonedDateTime now = ZonedDateTime.now(amsterdam); // => 2014-05-15T19:00:03.557+02:00[Europe/Amsterdam] ! now.withZoneSameInstant(chicago); // => 2014-05-15T12:00:03.557-05:00[America/Chicago] ! now.withZoneSameLocal(chicago); // => 2014-05-15T19:00:03.557-05:00[America/Chicago]
  6. Misc Information Year year = Year.now(); year.getValue(); // => 2014

    ! year.isLeap(); // => false ! year.length(); // => 365
  7. Just a bit of madness left DateTimeFormatter formatter =
 DateTimeFormatter.ofPattern("MMM

    dd, yyyy"); ! LocalDate today = LocalDate.of(2014, 5, 15); ! today.format(formatter); // => May 15, 2014
  8. Repeatable Annotations @Example("java 8") @Example("annotations") class Java8AnnotationExamples { .. }

    ! Java8AnnotationExamples.class.getAnnotationsByType( Example.class) // => [@Example(value=java 8),
 @Example(value=annotations)]
  9. How it works @Repeatable(Examples.class) public @interface Example { String value();

    } ! public @interface Examples { Example[] value(); }
  10. Depletion ! static Map<String, Leak> leaks = new HashMap<>(); !

    for (int i = 0; i < iterations; ++i) { String fakeJar = "file:" + i + ".jar"; URLClassLoader uniqueClassLoader =
 createClassLoader(fakeJar); Leak leak = (Leak) Proxy.newProxyInstance(
 uniqueClassLoader, new Class<?>[] { Leak.class }, new LeakInvocationHandler()); leaks.put(fakeJar, leak); }
  11. PermGen Depletion $ java_home 1.7 -exec java \
 KlassLeaker --iterations

    50000
 
 java.lang.OutOfMemoryError: PermGen space
  12. Metaspace Depletion $ java_home 1.8 -exec java -XX:MaxMetaspaceSize=128m \
 KlassLeaker

    --iterations 50000
 
 java.lang.OutOfMemoryError: Metaspace
  13. Nashorn $ java_home 1.8 -exec jjs jjs> print('Hello, World!')
 Hello,

    World! ! jjs> var plus = function(acc, n) { return acc + n } jjs> [1,2,3].reduce(plus)
 6 !
  14. Actual JavaScript
 (no ints) jjs> typeof 1
 number ! jjs>

    ['1','1','1'].map(parseInt)
 1,NaN,1 ! jjs> [1,2,3].map(parseInt)
 1,NaN,NaN
  15. Java Interoperability jjs> var Date = Java.type('java.time.LocalDate') ! jjs> var

    today = Date.now() jjs> today
 2014-05-15 ! jjs> today.year
 2014 !
  16. But… jjs> var IntStream = \
 Java.type(‘java.util.stream.IntStream’) ! jjs> var

    Range = IntStream.range jjs> Range(1,10).toArray()
 [I@78b729e6 !
  17. JavaScript Libraries jjs> load(‘http://cdnjs.cloudflare.com/ajax/libs/ underscore.js/1.6.0/underscore-min.js') ! jjs> var range =

    Range(1, 6).toArray() jjs> _.inject(range,
 function(acc, n) { return acc * n })
 120 jjs> 

  18. ScriptEngine ScriptEngineManager factory =
 new ScriptEngineManager(); ScriptEngine nashorn =
 factory.getEngineByName("nashorn");

    ! nashorn.eval(“function now() { return new Date }“); ! Invocable invocable = (Invocable) nashorn; invocable.invokeFunction(“now") // => [Date 2014-05-15T17:00:03.557Z]
  19. Using JavaScript libraries from Java nashorn.eval("load('http://cdnjs.cloudflare.com/ajax/ libs/underscore.js/1.6.0/underscore-min.js')"); ! nashorn.eval("function underscore()

    { return _ }"); ! Object underscore =
 invocable.invokeFunction("underscore"); invocable.invokeFunction(underscore, “head", new int[] { 1,2,3,4,5 }); // => 1
  20. “Functions” as Anonymous Objects writeToFile("todo.txt", new FileWriteFunction() { @Override public

    void apply(Writer file) throws IOException { file.write("learn about lambdas\n"); file.write("learn stream API\n"); } })
  21. Closures String todoList = "learn about lambdas\n" + "learn stream

    API\n"; ! writeToFile("todo.txt", file -> { file.write(todoList); })
  22. Just a spoonful of Syntactic Sugars? public class Lambdas {

    public void run(Function<String> fn) { System.out.println(fn.apply()); } ! public static void main(String[] args) { new Lambdas().run( () -> "Hello, World!"); } }
  23. Just a spoonful of Syntactic Sugars? $ java_home 1.8 -exec

    javap -p Lambdas
 Compiled from "Lambdas.java"
 public class Lambdas {
 public Lambdas();
 public void run(Function<java.lang.String>);
 public static void main(java.lang.String[]);
 private static java.lang.String lambda$main$0();
 }
  24. How it works $ java_home 1.8 -exec javap -c Lambdas


    
 public static void main(java.lang.String[]);
 Code:
 0: new #6 // class Lambdas
 3: dup
 4: invokespecial #7 // Method "<init>":()V
 7: invokedynamic #8, 0 // InvokeDynamic #0:apply: ()LFunction;
 12: invokevirtual #9 // Method run:(LFunction;)V
 15: return
  25. java.util.stream.Stream Collection.stream() ! -> filter :: [a] -> (a->Boolean) ->

    [a] ! -> map :: [a] -> (a->b) -> [b] ! -> reduce :: [a] -> r -> (r->a->r) -> r ! -> collect :: [a] -> ([a]->b) -> b
  26. Making (more) sense of Collections range(1,6).stream() .count() // => 5

    .reduce(0, (acc, n) -> acc * n ) // => 120 .map( n -> n * n ).collect(toList()) // => [1,4,9,16,25] .filter( n -> n % 2 == 0 ).collect(toList()) // => [2,4]
  27. Optional interface UserStore { Optional<User> find(Long id); } ! Optional<User>

    user = userStore.find(1L); ! String lastname = user.map(User::getLastname) .orElse(""); ! user.ifPresent(passwordReset::send);
  28. Higher-Order Functions <T> Function1<T, Boolean> complement(
 Function1<T, Boolean> fn) {

    return t -> ! fn.apply(t); } ! Function1<Integer, Boolean> adult = n -> n >= 18; Function1<Integer, Boolean> child = complement(adult); adult.apply(21); // => true child.apply(21); // => false
  29. Default Implementation public interface Collector<E> { ! boolean isEmpty(); !

    default boolean nonEmpty() { return ! isEmpty(); } }
  30. java.util.Base64 Base64.Encoder encoder = Base64.getEncoder(); Base64.Decoder decoder = Base64.getDecoder(); !

    String input = "Hello, World!"; byte[] base64 =
 encoder.encode(input.getBytes("UTF-8")); ! new String(base64, "UTF-8"); // => SGVsbG8sIFdvcmxkIQ== ! new String(decoder.decode(base64), "UTF-8"); // => Hello, World! !