Download - JavaOne 2013: Java 8 - The Good Parts

Transcript
Page 1: JavaOne 2013: Java 8 - The Good Parts

START

Page 2: JavaOne 2013: Java 8 - The Good Parts

Movie Time!

Page 3: JavaOne 2013: Java 8 - The Good Parts
Page 4: JavaOne 2013: Java 8 - The Good Parts

Andrzej Grzesik Konrad Malawski

Page 5: JavaOne 2013: Java 8 - The Good Parts

JAVA 8

Andrzej Grzesik Konrad Malawski

Page 6: JavaOne 2013: Java 8 - The Good Parts

JAVA 8THE GOOD PARTS

Andrzej Grzesik Konrad Malawski

Page 8: JavaOne 2013: Java 8 - The Good Parts

ABOUT:ME

Page 9: JavaOne 2013: Java 8 - The Good Parts

 

Konrad `@ktosopl` Malawski

Page 10: JavaOne 2013: Java 8 - The Good Parts

 

Konrad `@ktosopl` Malawski

Page 11: JavaOne 2013: Java 8 - The Good Parts

OUR OPINIONSARE OUR OWN

disclaimer

Page 12: JavaOne 2013: Java 8 - The Good Parts

QUESTIONS?

Page 13: JavaOne 2013: Java 8 - The Good Parts

QUESTIONS?ask them right away!

Page 14: JavaOne 2013: Java 8 - The Good Parts

JAVA 8 is going to be amazing!

Page 15: JavaOne 2013: Java 8 - The Good Parts

TWITTER SAYS:

Page 16: JavaOne 2013: Java 8 - The Good Parts

JAVA 8 IS THE NEW GUAVA

THE MOST EXCITING RELEASE IN HISTORY

Page 17: JavaOne 2013: Java 8 - The Good Parts

DONE WITH COMMUNITY

Page 19: JavaOne 2013: Java 8 - The Good Parts
Page 20: JavaOne 2013: Java 8 - The Good Parts
Page 21: JavaOne 2013: Java 8 - The Good Parts

YOU CAN HELP!

Page 22: JavaOne 2013: Java 8 - The Good Parts

FIX TESTHACK

DOCUMENT

Page 23: JavaOne 2013: Java 8 - The Good Parts

ADOPTOPENJDK.JAVA.NET

Page 24: JavaOne 2013: Java 8 - The Good Parts

ADOPTAJSR.JAVA.NET

Page 25: JavaOne 2013: Java 8 - The Good Parts

HOW DO I CHECK JDK8?

Page 26: JavaOne 2013: Java 8 - The Good Parts

JDK8.JAVA.NET

Page 27: JavaOne 2013: Java 8 - The Good Parts

IDE SUPPORT

Page 28: JavaOne 2013: Java 8 - The Good Parts
Page 29: JavaOne 2013: Java 8 - The Good Parts

JENVhttp://jenv.be

Page 30: JavaOne 2013: Java 8 - The Good Parts

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)

Page 31: JavaOne 2013: Java 8 - The Good Parts

JENV

ktoso @ 月/tmp$ jenv local oracle64-1.7.0.40

Page 32: JavaOne 2013: Java 8 - The Good Parts

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

Page 33: JavaOne 2013: Java 8 - The Good Parts

NEW TIME APIjsr 310

Page 34: JavaOne 2013: Java 8 - The Good Parts

void immutable() { LocalTime aTime = LocalTime.now(); print("now: %s", aTime);

LocalTime newTime = aTime.plusMinutes(16); print("now: %s, later: %s", aTime, newTime); }

Page 35: JavaOne 2013: Java 8 - The Good Parts

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

Page 36: JavaOne 2013: Java 8 - The Good Parts

now: 01:25:56.916later: 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

Page 37: JavaOne 2013: Java 8 - The Good Parts

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(); }

Page 38: JavaOne 2013: Java 8 - The Good Parts

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); }

Page 39: JavaOne 2013: Java 8 - The Good Parts

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

Page 40: JavaOne 2013: Java 8 - The Good Parts

ISO BY DEFAULT

Page 41: JavaOne 2013: Java 8 - The Good Parts

NO MOREnew SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");

Page 42: JavaOne 2013: Java 8 - The Good Parts

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)); }

Page 43: JavaOne 2013: Java 8 - The Good Parts

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

Page 44: JavaOne 2013: Java 8 - The Good Parts

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

Page 45: JavaOne 2013: Java 8 - The Good Parts

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.java:297)! (..)!*/ }

Page 47: JavaOne 2013: Java 8 - The Good Parts

APIENHANCEMENTS

Page 48: JavaOne 2013: Java 8 - The Good Parts

BETTER IO

Page 49: JavaOne 2013: Java 8 - The Good Parts

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()}

Page 50: JavaOne 2013: Java 8 - The Good Parts

MAPS

Page 51: JavaOne 2013: Java 8 - The Good Parts

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) { // ... } }); }

Page 52: JavaOne 2013: Java 8 - The Good Parts

void computeWithLambdas() { Map<Key, Value> map = // ...

map.computeIfAbsent(aKey, key -> { // ... });

map.computeIfPresent(aKey, (key, value) -> { // ... }); }

Page 53: JavaOne 2013: Java 8 - The Good Parts

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)}

Page 54: JavaOne 2013: Java 8 - The Good Parts

[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()); }

Page 55: JavaOne 2013: Java 8 - The Good Parts

void parallelPrefix() { int[] array = { 1, 2, 4, 8 };

Arrays.parallelPrefix(array, (left, right) -> { return left + right; }); }

Page 56: JavaOne 2013: Java 8 - The Good Parts

LAMBDAS?

Page 57: JavaOne 2013: Java 8 - The Good Parts

LAMBDAS!(finally)

Page 58: JavaOne 2013: Java 8 - The Good Parts

LAMBDAS

Notable inspirations would be:

ScalaGroovyLisps

.NOT (!)

Page 59: JavaOne 2013: Java 8 - The Good Parts

() -> {}

LAMBDAS

Page 60: JavaOne 2013: Java 8 - The Good Parts

LAMBDAS

(Thing t) -> {}

Page 61: JavaOne 2013: Java 8 - The Good Parts

LAMBDAS

Page 62: JavaOne 2013: Java 8 - The Good Parts

LAMBDAS

(Thing t) -> {}

Page 63: JavaOne 2013: Java 8 - The Good Parts

LAMBDAS

(Thing t) -> {}

(Thing t, More m) -> {}

Page 64: JavaOne 2013: Java 8 - The Good Parts

LAMBDAS & TYPES

Page 65: JavaOne 2013: Java 8 - The Good Parts

LAMBDAS & TYPES

GetNum _ = (t) -> {42}

Page 66: JavaOne 2013: Java 8 - The Good Parts

LAMBDAS & TYPES

GetNum _ = (t) -> {42}GetNum _ = (t) -> 42

Page 67: JavaOne 2013: Java 8 - The Good Parts

LAMBDAS & TYPES

GetNum _ = (t) -> {42}GetNum _ = (t) -> 42GetNum _ = t -> 1337

Page 68: JavaOne 2013: Java 8 - The Good Parts

interface Adder { void add(int a, int b);}

TARGET TYPING

Page 69: JavaOne 2013: Java 8 - The Good Parts

interface Adder { void add(int a, int b);}

TARGET TYPING

Adder function = (int a, int b) -> { a + b };

Page 70: JavaOne 2013: Java 8 - The Good Parts

interface Adder { void add(int a, int b);}

TARGET TYPING

Adder function = (int a, int b) -> { a + b };

Page 71: JavaOne 2013: Java 8 - The Good Parts

interface Adder { void add(int a, int b);}

TARGET TYPING

Adder function = (int a, int b) -> { a + b };

(int, int) => int

gets converted into target type:

Adder

Page 72: JavaOne 2013: Java 8 - The Good Parts

interface Adder { void add(int a, int b);}

TARGET TYPING

Adder function = (int a, int b) -> { a + b };

// or shorter:

Adder function = (a, b) -> a + b;

Page 73: JavaOne 2013: Java 8 - The Good Parts

interface Adder { void add(int a, int b);}

TARGET TYPING

Adder function = (int a, int b) -> { a + b };

// or shorter:

Adder function = (a, b) -> a + b;

You can skip the ; sign!

Page 74: JavaOne 2013: Java 8 - The Good Parts

interface Adder { void add(int a, int b);}

TARGET TYPING

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!

Page 75: JavaOne 2013: Java 8 - The Good Parts

interface Adder { void add(int a, int b);}

TARGET TYPING

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!

Page 76: JavaOne 2013: Java 8 - The Good Parts

FUNCTIONAL INTERFACES

interface Adder { void add(int a, int b);}

Page 77: JavaOne 2013: Java 8 - The Good Parts

FUNCTIONAL INTERFACES

@FunctionalInterfaceinterface Adder { void add(int a, int b);}

Page 78: JavaOne 2013: Java 8 - The Good Parts

FUNCTIONAL INTERFACES

@FunctionalInterfaceinterface Adder { void add(int a, int b);}

Similar to @Override: * not required,* checks our intent.

Page 79: JavaOne 2013: Java 8 - The Good Parts

FUNCTIONAL INTERFACES

@FunctionalInterfaceinterface Adder { void add(int a, int b); void wat();}

Page 80: JavaOne 2013: Java 8 - The Good Parts

FUNCTIONAL INTERFACES

@FunctionalInterfaceinterface 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

Page 81: JavaOne 2013: Java 8 - The Good Parts

DEFAULT METHODS

@FunctionalInterfaceinterface Adder { void add(int a, int b); default void wat() { /* nothing... */ }}

OK!Only 1 abstract method.

Page 82: JavaOne 2013: Java 8 - The Good Parts

DEFAULT METHODS@FunctionalInterfaceinterface Adder { default int add(int a, int b) { return a + b; }}

@FunctionalInterfaceinterface 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); }}

Page 83: JavaOne 2013: Java 8 - The Good Parts

DEFAULT METHODS

We mixed in methods!

here! and here!

@FunctionalInterfaceinterface Adder { default int add(int a, int b) { return a + b; }}

@FunctionalInterfaceinterface 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); }}

Page 84: JavaOne 2013: Java 8 - The Good Parts

interface A { default void doIt() { /* A */ }}

interface B { default void doIt() { /* B */ }}

class Thing implements A, B {}

DEFAULT METHODS

Page 85: JavaOne 2013: Java 8 - The Good Parts

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

Page 86: JavaOne 2013: Java 8 - The Good Parts

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!

Page 87: JavaOne 2013: Java 8 - The Good Parts

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!

Page 88: JavaOne 2013: Java 8 - The Good Parts

DEFAULT IN ITERABLEpackage java.lang;

@FunctionalInterfacepublic 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); } }

Page 89: JavaOne 2013: Java 8 - The Good Parts

void withoutLambda() { button.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { System.out.println("example"); } }); }

λ IN ACTION

Page 90: JavaOne 2013: Java 8 - The Good Parts

BEFORE LAMBDASin IntelliJ

Page 91: JavaOne 2013: Java 8 - The Good Parts

void withLambda() { button.addActionListener((e) -> { System.out.println("example"); }); }

λ IN ACTION

Page 92: JavaOne 2013: Java 8 - The Good Parts

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);

}

Page 93: JavaOne 2013: Java 8 - The Good Parts

REMOVING BOILERPLATE

Page 94: JavaOne 2013: Java 8 - The Good Parts

STREAMS

Page 95: JavaOne 2013: Java 8 - The Good Parts

void transform() { Iterables.transform( newArrayList(1, 2, 3), new Function<Integer, String>() { @Override public String apply(Integer input) { return input.toString(); } }); }

Page 96: JavaOne 2013: Java 8 - The Good Parts

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

Page 97: JavaOne 2013: Java 8 - The Good Parts

items.stream().map(Item::getName);

compared to Scala

items map { _.getName }

Page 98: JavaOne 2013: Java 8 - The Good Parts

items.stream().map(Item::getName);

yay, we’re cool now!

compared to Scala

items map { _.getName }

Page 99: JavaOne 2013: Java 8 - The Good Parts

STREAMS

items.stream().

filter(predicate); map(mapper); mapToInt(mapper); flatMap(mapper); distinct(); sorted(); sorted(comparator); peek(consumer); limit(maxSize); forEach(func);

Page 100: JavaOne 2013: Java 8 - The Good Parts

INTERNAL ITERATION void internalIteration() { List<Thing> things = ...;

things.forEach(System.out::println); }

Page 101: JavaOne 2013: Java 8 - The Good Parts

PARALLELIZE?

Page 102: JavaOne 2013: Java 8 - The Good Parts

PARALLEL ITERATION

void parallelIteration() { List<Thing> things = ...;

things.parallelStream().forEach(System.out::println); }

Page 103: JavaOne 2013: Java 8 - The Good Parts

STREAMS ARE LAZY!

Page 104: JavaOne 2013: Java 8 - The Good Parts

List<Integer> is = newArrayList(1, 2, 3);

is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a));

STREAMS ARE LAZY

Page 105: JavaOne 2013: Java 8 - The Good Parts

List<Integer> is = newArrayList(1, 2, 3);

is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a));

Prints:

STREAMS ARE LAZY

Page 106: JavaOne 2013: Java 8 - The Good Parts

List<Integer> is = newArrayList(1, 2, 3);

is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a));

Prints:

STREAMS ARE LAZY

Nothing!

Page 107: JavaOne 2013: Java 8 - The Good Parts

STREAMS ARE LAZYList<Integer> is = newArrayList(1, 2, 3);

is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a)) .collect(toList());

Page 108: JavaOne 2013: Java 8 - The Good Parts

STREAMS ARE LAZYList<Integer> is = newArrayList(1, 2, 3);

is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a)) .collect(toList());

Prints:

A1B1A2B2A3B3

Page 109: JavaOne 2013: Java 8 - The Good Parts

STREAMS ARE LAZYList<Integer> is = newArrayList(1, 2, 3);

is.stream() .map(a -> printAndReturn("A", a)) .map(a -> printAndReturn("B", a)) .collect(toList());

Prints:

A1B1A2B2A3B3

It’s ONE iteration!

Page 110: JavaOne 2013: Java 8 - The Good Parts

METHOD HANDLESthink function pointers

Page 111: JavaOne 2013: Java 8 - The Good Parts

KEEPING REFERENCES

??? method = Person::getName

class Person { String getName();}

?

Page 112: JavaOne 2013: Java 8 - The Good Parts

KEEPING REFERENCES

Supplier<String> method = Person::getName

@FunctionalInterfacepublic interface Supplier<T> { T get();}

class Person { String getName();}

Page 113: JavaOne 2013: Java 8 - The Good Parts

void referringToMethods() { String name = Person.getName();

String name = applyTo(heinz, Person::getName); }

Page 114: JavaOne 2013: Java 8 - The Good Parts

REFERRING TO 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);}

Page 115: JavaOne 2013: Java 8 - The Good Parts

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...!

Page 116: JavaOne 2013: Java 8 - The Good Parts

Fact: in order to refer to:

String doThing(String a, String b, String c, Integer d);

JAVA.UTIL.FUNCTION.*

Page 117: JavaOne 2013: Java 8 - The Good Parts

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.*

Page 118: JavaOne 2013: Java 8 - The Good Parts

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.*

Page 120: JavaOne 2013: Java 8 - The Good Parts

THANK YOU!

Page 121: JavaOne 2013: Java 8 - The Good Parts

@ags313

Andrzej Grzesik Konrad Malawski

@ktosopl

TWEET PLEASE!