Your SlideShare is downloading. ×
Java 8: the good parts!
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Java 8: the good parts!

5,156
views

Published on

As presented at JavaOne session UGF10520 by me and @ktosopl

As presented at JavaOne session UGF10520 by me and @ktosopl

Published in: Technology, News & Politics

1 Comment
7 Likes
Statistics
Notes
  • Great insight to java 8 features. Thanks for the presentation
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
5,156
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
115
Comments
1
Likes
7
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. START
  • 2. MovieTime!
  • 3. Andrzej Grzesik Konrad Malawski
  • 4. JAVA 8 Andrzej Grzesik Konrad Malawski
  • 5. JAVA 8 THE GOOD PARTS Andrzej Grzesik Konrad Malawski
  • 6. @ags313 andrzej@grzesik.it andrzejgrzesik.info Andrzej Grzesik
  • 7. ABOUT:ME
  • 8.   Konrad `@ktosopl` Malawski
  • 9.   Konrad `@ktosopl` Malawski
  • 10. OUR OPINIONS ARE OUR OWN disclaimer
  • 11. QUESTIONS?
  • 12. QUESTIONS? ask them right away!
  • 13. JAVA 8 is going to be amazing!
  • 14. TWITTER SAYS:
  • 15. JAVA 8 ISTHE NEW GUAVA THE MOST EXCITING RELEASE IN HISTORY
  • 16. DONE WITH COMMUNITY
  • 17. ADOPT OPENJDK adoptopenjdk.java.net
  • 18. YOU CAN HELP!
  • 19. FIX TEST HACK DOCUMENT
  • 20. ADOPTOPENJDK.JAVA.NET
  • 21. ADOPTAJSR.JAVA.NET
  • 22. HOW DO I CHECK JDK8?
  • 23. JDK8.JAVA.NET
  • 24. IDE SUPPORT
  • 25. JENV http://jenv.be
  • 26. JENV $ jenv versions system oracle64-1.6.0.51 oracle64-1.7.0.40 * oracle64-1.8.0-ea (set by /Users/ktoso/.jenv/version)
  • 27. JENV ktoso @ 月/tmp $ jenv local oracle64-1.7.0.40
  • 28. JENV ktoso @ 月/tmp $ jenv versions systema oracle64-1.6.0.51 * oracle64-1.7.0.40 (set by /tmp/.java-version) oracle64-1.8.0-ea ktoso @ 月/tmp $ jenv local oracle64-1.7.0.40
  • 29. NEWTIME API jsr 310
  • 30. void immutable() { LocalTime aTime = LocalTime.now(); print("now: %s", aTime); LocalTime newTime = aTime.plusMinutes(16); print("now: %s, later: %s", aTime, newTime); }
  • 31. void immutable() { LocalTime aTime = LocalTime.now(); print("now: %s", aTime); LocalTime newTime = aTime.plusMinutes(16); print("now: %s, later: %s", aTime, newTime); } now: 01:25:56.916
  • 32. now: 01:25:56.916 later: 01:41:56.916 void immutable() { LocalTime aTime = LocalTime.now(); print("now: %s", aTime); LocalTime newTime = aTime.plusMinutes(16); print("now: %s, later: %s", aTime, newTime); } now: 01:25:56.916
  • 33. private void localTime() { LocalDate today = LocalDate.now(); LocalDate yesterday = today.minusDays(1); // Geek Bike Ride! LocalDateTime localDateTime = yesterday.atTime(11, 30); LocalDateTime earlyMorning = LocalDate.of(2013, 9, 22) .atStartOfDay(); }
  • 34. void flightTime() { ZoneId LHR = ZoneId.of("Europe/London"); ZoneId SFO = ZoneId.of("America/Los_Angeles"); LocalDate date = LocalDate.of(2013, Month.SEPTEMBER, 14); LocalTime takeoff = LocalTime.of(12, 50); LocalTime landing = LocalTime.of(16, 20); Duration flightTime = Duration.between( ZonedDateTime.of(date, takeoff, LHR), ZonedDateTime.of(date, landing, SFO)); System.out.println("Flight time: " + flightTime); }
  • 35. void flightTime() { ZoneId LHR = ZoneId.of("Europe/London"); ZoneId SFO = ZoneId.of("America/Los_Angeles"); LocalDate date = LocalDate.of(2013, Month.SEPTEMBER, 14); LocalTime takeoff = LocalTime.of(12, 50); LocalTime landing = LocalTime.of(16, 20); Duration flightTime = Duration.between( ZonedDateTime.of(date, takeoff, LHR), ZonedDateTime.of(date, landing, SFO)); System.out.println("Flight time: " + flightTime); } Flight time: PT11H30M
  • 36. ISO BY DEFAULT
  • 37. NO MORE new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
  • 38. void formatting() { DateTimeFormatter.ISO_DATE. format(LocalDateTime.of(2013, 9, 22, 10, 03)); DateTimeFormatter.ISO_DATE_TIME. format(LocalDateTime.of(2013, 9, 22, 10, 30)); }
  • 39. void formatting() { DateTimeFormatter.ISO_DATE. format(LocalDateTime.of(2013, 9, 22, 10, 03)); DateTimeFormatter.ISO_DATE_TIME. format(LocalDateTime.of(2013, 9, 22, 10, 30)); } 2013-09-22
  • 40. void formatting() { DateTimeFormatter.ISO_DATE. format(LocalDateTime.of(2013, 9, 22, 10, 03)); DateTimeFormatter.ISO_DATE_TIME. format(LocalDateTime.of(2013, 9, 22, 10, 30)); } 2013-09-22 2013-09-22T10:30:00
  • 41. void formatterError() { ISO_DATE_TIME.format(LocalDate.of(2013, 9, 22)); /* Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay ! at java.time.LocalDate.get0(LocalDate.java:670) ! at java.time.LocalDate.getLong(LocalDate.java:649) ! at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.ja va:297) ! (..)! */ }
  • 42. TUTORIAL http://docs.oracle.com/javase/tutorial/datetime/index.html
  • 43. API ENHANCEMENTS
  • 44. BETTER IO
  • 45. void betterIO() { BufferedReader bufferedReader; Path path; Stream<String> lines = bufferedReader.lines(); Stream<String> lines = Files.lines(Path, Charset); Stream<Path> paths = Files.list(Path); Stream<Path> paths = Files.find(Path, depth, BiPredicate, FileVisitOption...) Stream<Path> paths = Files.walk(Path, depth, FileVisitOption...) Stream<Path> paths = Files.walk(Path, FileVisitOption...) DirectoryStream.stream() }
  • 46. MAPS
  • 47. compute() { map.compute(aKey, new BiFunction<Key, Value, Value>() { @Override public Value apply(Key key, Value value) { // ... } }); map.computeIfAbsent(aKey, new Function<Key, Value>() { @Override public Value apply(Key key) { // ... } }); map.computeIfPresent(aKey, new BiFunction<Key, Value, Value>() { @Override public Value apply(Key key, Value value) { // ... } }); }
  • 48. void computeWithLambdas() { Map<Key, Value> map = // ... map.computeIfAbsent(aKey, key -> { // ... }); map.computeIfPresent(aKey, (key, value) -> { // ... }); }
  • 49. void moreMaps() { Map<Key, Value> map = null; map.putIfAbsent(K, V); map.remove(Object, Object); map.replace(K, V); // Compare and swap map.replace(K, V1, V2); map.replaceAll(BiFunction); map.getOrDefault(K, V); map.merge(K, V, BiFunction) }
  • 50. [5, 8, 6, 7, 2, 1, 4, 3] void parallelSetAll() { int[] array = new int[8]; AtomicInteger i = new AtomicInteger(); Arrays.parallelSetAll(array, operand -> i.incrementAndGet()); }
  • 51. void parallelPrefix() { int[] array = { 1, 2, 4, 8 }; Arrays.parallelPrefix(array, (left, right) -> { return left + right; }); }
  • 52. LAMBDAS?
  • 53. LAMBDAS! (finally)
  • 54. LAMBDAS Notable inspirations would be: Scala Groovy Lisps .NOT (!)
  • 55. () -> {} LAMBDAS
  • 56. LAMBDAS (Thing t) -> {}
  • 57. LAMBDAS
  • 58. LAMBDAS (Thing t) -> {}
  • 59. LAMBDAS (Thing t) -> {} (Thing t, More m) -> {}
  • 60. LAMBDAS &TYPES
  • 61. LAMBDAS &TYPES GetNum _ = (t) -> {42}
  • 62. LAMBDAS &TYPES GetNum _ = (t) -> {42} GetNum _ = (t) -> 42
  • 63. LAMBDAS &TYPES GetNum _ = (t) -> {42} GetNum _ = (t) -> 42 GetNum _ = t -> 1337
  • 64. interface Adder { void add(int a, int b); } TARGETTYPING
  • 65. interface Adder { void add(int a, int b); } TARGETTYPING Adder function = (int a, int b) -> { a + b };
  • 66. interface Adder { void add(int a, int b); } TARGETTYPING Adder function = (int a, int b) -> { a + b };
  • 67. interface Adder { void add(int a, int b); } TARGETTYPING Adder function = (int a, int b) -> { a + b }; (int, int) => int gets converted into target type: Adder
  • 68. interface Adder { void add(int a, int b); } TARGETTYPING Adder function = (int a, int b) -> { a + b }; // or shorter: Adder function = (a, b) -> a + b;
  • 69. interface Adder { void add(int a, int b); } TARGETTYPING Adder function = (int a, int b) -> { a + b }; // or shorter: Adder function = (a, b) -> a + b; You can skip the ; sign!
  • 70. interface Adder { void add(int a, int b); } TARGETTYPING Adder function = (int a, int b) -> { a + b }; // or shorter: Adder function = (a, b) -> a + b; You can skip { } sometimes You can skip the ; sign!
  • 71. interface Adder { void add(int a, int b); } TARGETTYPING Adder function = (int a, int b) -> { a + b }; // or shorter: Adder function = (a, b) -> a + b; You can skip { } sometimes You can skip the ; sign! and the types are inferred!
  • 72. FUNCTIONAL INTERFACES interface Adder { void add(int a, int b); }
  • 73. FUNCTIONAL INTERFACES @FunctionalInterface interface Adder { void add(int a, int b); }
  • 74. FUNCTIONAL INTERFACES @FunctionalInterface interface Adder { void add(int a, int b); } Similar to @Override: * not required, * checks our intent.
  • 75. FUNCTIONAL INTERFACES @FunctionalInterface interface Adder { void add(int a, int b); void wat(); }
  • 76. FUNCTIONAL INTERFACES @FunctionalInterface interface Adder { void add(int a, int b); void wat(); } java: Unexpected @FunctionalInterface annotation pl.project13.lambda.test.examples.Adder is not a functional interface multiple non-overriding abstract methods found in interface pl.project13.lambda.test.examples.Adder
  • 77. DEFAULT METHODS @FunctionalInterface interface Adder { void add(int a, int b); default void wat() { /* nothing... */ } } OK! Only 1 abstract method.
  • 78. DEFAULT METHODS @FunctionalInterface interface Adder { default int add(int a, int b) { return a + b; } } @FunctionalInterface interface Divider { default double divide(int a, int b) { return a / b; } } class Calculator implements Adder, Divider { public double calc(int a, int b, int c) { return divide(add(a, b), c); } }
  • 79. DEFAULT METHODS We mixed in methods! here! and here! @FunctionalInterface interface Adder { default int add(int a, int b) { return a + b; } } @FunctionalInterface interface Divider { default double divide(int a, int b) { return a / b; } } class Calculator implements Adder, Divider { public double calc(int a, int b, int c) { return divide(add(a, b), c); } }
  • 80. interface A { default void doIt() { /* A */ } } interface B { default void doIt() { /* B */ } } class Thing implements A, B { } DEFAULT METHODS
  • 81. interface A { default void doIt() { /* A */ } } interface B { default void doIt() { /* B */ } } class Thing implements A, B { } DEFAULT METHODS java: class com.javaone.Thing inherits unrelated defaults for doIt() from types com.javaone.A and com.javaone.B
  • 82. DEFAULT METHODS interface A { default void doIt() { /* A */ } } interface B { default void doIt() { /* B */ } } class Thing implements A, B { @Override public void doIt() { A.super.doIt(); } } Resolve ambiguity manually!
  • 83. DEFAULT METHODS interface A { default void doIt() { /* A */ } } interface B { default void doIt() { /* B */ } } class Thing implements A, B { @Override public void doIt() { A.super.doIt(); } } Resolve ambiguity manually!
  • 84. DEFAULT IN ITERABLE package java.lang; @FunctionalInterface public interface Iterable<T> { Iterator<T> iterator(); /** @since 1.8 */ default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
  • 85. void withoutLambda() { button.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { System.out.println("example"); } }); } λ IN ACTION
  • 86. BEFORE LAMBDAS in IntelliJ
  • 87. void withLambda() { button.addActionListener((e) -> { System.out.println("example"); }); } λ IN ACTION
  • 88. void composingFunctions() { // given Function<Integer, Integer> timesTwo = n -> n * 2; Function<Integer, Integer> plusOne = n -> n + 1; // when Function<Integer, Integer> multiplyThenAdd = timesTwo.andThen(plusOne); // equivalent to Function<Integer, Integer> multiplyThenAdd = plusOne.compose(timesTwo); // then int result = multiplyThenAdd.apply(1); assertThat(result).isEqualTo(3); }
  • 89. REMOVING BOILERPLATE
  • 90. STREAMS
  • 91. void transform() { Iterables.transform( newArrayList(1, 2, 3), new Function<Integer, String>() { @Override public String apply(Integer input) { return input.toString(); } }); }
  • 92. void transform() { Iterables.transform( newArrayList(1, 2, 3), new Function<Integer, String>() { @Override public String apply(Integer input) { return input.toString(); } }); } void noMoreTransform() { items.stream().map(i -> i.toString()); } vs
  • 93. items.stream().map(Item::getName); compared to Scala items map { _.getName }
  • 94. items.stream().map(Item::getName); yay, we’re cool now! compared to Scala items map { _.getName }
  • 95. STREAMS items.stream(). filter(predicate); map(mapper); mapToInt(mapper); flatMap(mapper); distinct(); sorted(); sorted(comparator); peek(consumer); limit(maxSize); forEach(func);
  • 96. INTERNAL ITERATION void internalIteration() { List<Thing> things = ...; things.forEach(System.out::println); }
  • 97. PARALLELIZE?
  • 98. PARALLEL ITERATION void parallelIteration() { List<Thing> things = ...; things.parallelStream().forEach(System.out::println); }
  • 99. STREAMS ARE LAZY!
  • 100. List<Integer> is = newArrayList(1, 2, 3); is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a)); STREAMS ARE LAZY
  • 101. List<Integer> is = newArrayList(1, 2, 3); is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a)); Prints: STREAMS ARE LAZY
  • 102. List<Integer> is = newArrayList(1, 2, 3); is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a)); Prints: STREAMS ARE LAZY Nothing!
  • 103. STREAMS ARE LAZY List<Integer> is = newArrayList(1, 2, 3); is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a)) .collect(toList());
  • 104. STREAMS ARE LAZY List<Integer> is = newArrayList(1, 2, 3); is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a)) .collect(toList()); Prints: A1 B1 A2 B2 A3 B3
  • 105. STREAMS ARE LAZY List<Integer> is = newArrayList(1, 2, 3); is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a)) .collect(toList()); Prints: A1 B1 A2 B2 A3 B3 It’s ONE iteration!
  • 106. METHOD HANDLES think function pointers
  • 107. KEEPING REFERENCES ??? method = Person::getName class Person { String getName(); } ?
  • 108. KEEPING REFERENCES Supplier<String> method = Person::getName @FunctionalInterface public interface Supplier<T> { T get(); } class Person { String getName(); }
  • 109. void referringToMethods() { String name = Person.getName(); String name = applyTo(heinz, Person::getName); }
  • 110. REFERRINGTO METHODS String normalName = heinz.getName(); String magicName = applyTo(heinz, Person::getName); public <T, R> R applyTo(T obj, Function<T, R> function) { return function.apply(obj); }
  • 111. JAVA.UTIL.FUNCTION.* Supplier<T> => T Consumer<T> T => void Predicate<T> T => Boolean BiPredicate<T1, T2> (T1, T2) => Boolean Function<T, R> T => R BiFunction<T1, T2, R> (T1, T2) => R and more...!
  • 112. Fact: in order to refer to: String doThing(String a, String b, String c, Integer d); JAVA.UTIL.FUNCTION.*
  • 113. Fact: in order to refer to: String doThing(String a, String b, String c, Integer d); you have to: @FunctionalInterface interface Function4<T1, T2, T3, T4, R> { R apply(T1 a, T2 b, T3 c, T4 d); } JAVA.UTIL.FUNCTION.*
  • 114. Fact: in order to refer to: String doThing(String a, String b, String c, Integer d); you have to: @FunctionalInterface interface Function4<T1, T2, T3, T4, R> { R apply(T1 a, T2 b, T3 c, T4 d); } Function4<String, String, String, Integer, String> fun = Example::doThing; JAVA.UTIL.FUNCTION.*
  • 115. BACKTOTHE FUTURE! ● http://cr.openjdk.java.net/~briangoetz/ lambda/collections-overview.html ● http://docs.oracle.com/javase/tutorial/java/javaOO/ lambdaexpressions.html ● http://www.techempower.com/blog/2013/03/26/ everything-about-java-8/ ● For fun, Lambda Spec: github.com/ktoso/lambda-spec
  • 116. THANKYOU!
  • 117. @ags313 Andrzej Grzesik Konrad Malawski @ktosopl TWEET PLEASE!