Java 8 Ondřej Hrstka Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Přednáška 13 A0B36PR2 Programování 2 Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 1 / 26
Obsah Lambda funkce Novinky v interfaces Default metody Statické metody Streamy Optional - aneb zbavujeme se null Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 2 / 26
Lambda výrazy (anonymní funkce) Ukážeme si na příkladu: //Java < 8 Comparator<String> lengthcomparator = new Comparator<>() { public int compare(string o1, String o2) { return o1.length() - o2.length(); } }; Collections.sort(list, lengthcomparator); Často se nám v kódu vyskytuje (anonymní) třída, která má pouze jednu metodu. Nemá žádné instanční proměnné. Dalším častým příkladem jsou listenery v GUI. Takový kód byl potom velmi nepřehledný. Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 3 / 26
Lambda výrazy (anonymní funkce) Ukážeme si na příkladu: //Java < 8 Comparator<String> lengthcomparator = new Comparator<>() { public int compare(string o1, String o2) { return o1.length() - o2.length(); } }; Collections.sort(list, lengthcomparator); Často se nám v kódu vyskytuje (anonymní) třída, která má pouze jednu metodu. Nemá žádné instanční proměnné. Dalším častým příkladem jsou listenery v GUI. Takový kód byl potom velmi nepřehledný. Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 3 / 26
Lambda výrazy (anonymní funkce) //Java 8 Comparator<String> lengthcomparator = (o1, o2) -> o1.length() - o2.length(); Collections.sort(list, lengthcomparator); //Anebo Collections.sort(list, (o1, o2) -> o1.length() - o2.length()); Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 3 / 26
Lambda výrazy (anonymní funkce) //Java 8 Comparator<String> lengthcomparator = (o1, o2) -> o1.length() - o2.length(); Collections.sort(list, lengthcomparator); //Anebo Collections.sort(list, (o1, o2) -> o1.length() - o2.length()); Zjednodušeně řečeno jedná o snažší vytvoření anonymní třídy. Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 3 / 26
Možné zápisy lambda výrazu Zápis pomocí anonymní třídy: new BiFunction<T1, T2, T3>() { @Override public T3 apply(t1 t1, T2 t2) { T3 t3; //... return t3; } }; Plný zápis : (T1 t1, T2 t2) -> { T3 t3; //... return t3; }; Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 4 / 26
Možné zápisy lambda výrazu Zápis pomocí anonymní třídy: new BiFunction<T1, T2, T3>() { @Override public T3 apply(t1 t1, T2 t2) { T3 t3; //... return t3; } }; Můžeme vynechat typy argumentů: (t1, t2) -> { T3 t3; //... return t3; }; Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 4 / 26
Možné zápisy lambda výrazu Zápis pomocí anonymní třídy: new BiFunction<T1, T2, T3>() { @Override public T3 apply(t1 t1, T2 t2) { return t1.somefunction(t2); } }; Pokud funkce obsahuje jedinný výraz, který by byl vracen pomocí return: (t1, t2) -> t1.somefunction(t2); Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 5 / 26
Možné zápisy lambda výrazu Jeden argument: x -> x + 10; Žádný argument, void funkce : () -> System.out.println("Hello world!"); Žádný argument, int funkce : () -> 42; Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 6 / 26
Souvislost s Closures Volná definice: Closure je funkce, která má přístupné všechny prvky (metody, proměnné) ve scope v kterém je definována. Ukázka closure:... boolean ascending = false; Comparator<String> comparator = (s1, s2) -> { int order = ascending? 1 : -1; return order * (o1.length() - o2.length()); }; return comparator;... Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 7 / 26
Souvislost s Closures Proměnné ke kterým je přistupováno z closure musí být effectively final: A variable or parameter whose value is never changed after it is initialized is effectively final. Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 7 / 26
Souvislost s Closures Proměnné ke kterým je přistupováno z closure musí být effectively final: A variable or parameter whose value is never changed after it is initialized is effectively final. Proč? Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 7 / 26
Reference na metody Často lambda funkce pouze volá jinou metodu. V takovém případě se nám vyplatí reference na metody. K tomuto se používá operátor :: Instanční metoda () -> this.bar(); this::bar; x -> foo.bar1(x); foo::bar1; Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 8 / 26
Reference na metody Často lambda funkce pouze volá jinou metodu. V takovém případě se nám vyplatí reference na metody. K tomuto se používá operátor :: Statická metoda x -> Math.sin(x); Math::sin(x); Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 8 / 26
Reference na metody Často lambda funkce pouze volá jinou metodu. V takovém případě se nám vyplatí reference na metody. K tomuto se používá operátor :: Konstruktor x -> new Foo(x); Foo::new; Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 8 / 26
Reference na metody Často lambda funkce pouze volá jinou metodu. V takovém případě se nám vyplatí reference na metody. K tomuto se používá operátor :: Instanční metoda argumentu (Foo foo) -> foo.tostring(); Foo::toString(); Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 8 / 26
@FunctionalInterface Pomocí lambdy můžeme vytvořit instanci libovolného interface, které má právě jednu instanční funkci. Pokud si chceme nechat tuto možnost pohlídat kompilátorem, můžeme označit interface anotací @FunctionalInterface @FunctionalInterface public interface Bar {... Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 9 / 26
Lambda funkce - shrnutí Java framework obsahuje v balíčku java.util.function předpřipravené funkční interfaces pro mnohá použití. Např.: Consumer<T>, Function<T,R>, Supplier<T>, Predicate<T>, BiFunction<T,U,R>, Consumer<T> Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 10 / 26
Lambda funkce - shrnutí Java framework obsahuje v balíčku java.util.function předpřipravené funkční interfaces pro mnohá použití. Např.: Consumer<T>, Function<T,R>, Supplier<T>, Predicate<T>, BiFunction<T,U,R>, Consumer<T> Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 10 / 26
Lambda funkce - shrnutí Java framework obsahuje v balíčku java.util.function předpřipravené funkční interfaces pro mnohá použití. Např.: Consumer<T>, Function<T,R>, Supplier<T>, Predicate<T>, BiFunction<T,U,R>, Consumer<T> Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 10 / 26
Lambda funkce - shrnutí Java framework obsahuje v balíčku java.util.function předpřipravené funkční interfaces pro mnohá použití. Např.: Consumer<T>, Function<T,R>, Supplier<T>, Predicate<T>, BiFunction<T,U,R>, Consumer<T> Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 10 / 26
Lambda funkce - shrnutí Java framework obsahuje v balíčku java.util.function předpřipravené funkční interfaces pro mnohá použití. Např.: Consumer<T>, Function<T,R>, Supplier<T>, Predicate<T>, BiFunction<T,U,R>, Consumer<T> Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 10 / 26
Lambda funkce - shrnutí Java framework obsahuje v balíčku java.util.function předpřipravené funkční interfaces pro mnohá použití. Např.: Consumer<T>, Function<T,R>, Supplier<T>, Predicate<T>, BiFunction<T,U,R>, Consumer<T> Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 10 / 26
Obsah Lambda funkce Novinky v interfaces Default metody Statické metody Streamy Optional - aneb zbavujeme se null Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 11 / 26
Default metoda - Motivace (jedna z mnoha) Když máme lambda funkce, dovedeme si představit metodu IterableforEach(Consumer<T> action), která pro danou instanci Iterable zavolá action na každou iterovanou položku. Tato metoda by plnila podobnou funkci jako operátor for-each, avšak v některých případech by mohla být optimalizována na konkrétní třídu. Proč nemůžeme tuto metodu přidat do další verze Javy? Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 12 / 26
Default metoda Java 8 zavádí klíčové slovo default které můžeme použít u deklerace metody v interface. Tato metoda může mít definované tělo přímo v interface. interface Foo { default void bar() { System.out.println("Hello world!"); foo(); } } void foo(); Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 13 / 26
Diamond problem interface A { default void foo() {} } interface B extends A { @Override default void foo() {...} } interface C extends A { @Override default void foo() {...} } public class D implements B, C {... } Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 14 / 26
Statické metody Interface nyní může obsahovat statické metody. Hodí se třeba jako factory metody public interface Comparator<T> {... public static <T, Comparable<U>> Comparator<T> comparing(function<t, U> keyextractor) {... } } (o1, o2) -> o1.length() - o2.length(); Comparator.comparing(String::length) Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 15 / 26
Statické metody Interface nyní může obsahovat statické metody. Hodí se třeba jako factory metody public interface Comparator<T> {... public static <T, Comparable<U>> Comparator<T> comparing(function<t, U> keyextractor) {... } } (o1, o2) -> o1.length() - o2.length(); Comparator.comparing(String::length) Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 15 / 26
Obsah Lambda funkce Novinky v interfaces Default metody Statické metody Streamy Optional - aneb zbavujeme se null Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 16 / 26
balíček java.util.stream umožňují zpracovávat data pomocí deklerativního zápisu Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 17 / 26
//Java 7 List<Transaction> grocerytransactions = new Arraylist <>(); for(transaction t: transactions){ if(t.gettype() == Transaction.GROCERY){ grocerytransactions.add(t); }} Collections.sort(groceryTransactions, new Comparator() { public int compare(transaction t1, Transaction t2){ return t2.getvalue().compareto(t1.getvalue()); }}); List<Integer> transactionids = new ArrayList<>(); for(transaction t: grocerytransactions){ transactionsids.add(t.getid()); } http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 18 / 26
//Java 8 List<Integer> transactionsids = transactions.stream().filter(t -> t.gettype() == Transaction.GROCERY).sorted(comparing(Transaction::getValue).reversed()).map(Transaction::getId).collect(toList()); http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 19 / 26
Vybrané metody Streamu filter map flatmap sorted collect parallel reduce Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 20 / 26
Vybrané metody Streamu filter map flatmap sorted collect parallel reduce Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 20 / 26
Vybrané metody Streamu filter map flatmap sorted collect parallel reduce Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 20 / 26
Vybrané metody Streamu filter map flatmap sorted collect parallel reduce Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 20 / 26
Vybrané metody Streamu filter map flatmap sorted collect parallel reduce Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 20 / 26
Vybrané metody Streamu filter map flatmap sorted collect parallel reduce Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 20 / 26
Vybrané metody Streamu filter map flatmap sorted collect parallel reduce Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 20 / 26
Obsah Lambda funkce Novinky v interfaces Default metody Statické metody Streamy Optional - aneb zbavujeme se null Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 21 / 26
I call it my billion-dollar mistake. It was the invention of the null reference in 1965. - Sir Charles Antony Richard Hoare https://en.wikipedia.org/wiki/tony_hoare Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 22 / 26
Když je null pointer tak špatný, tak se ho zbavme. Ale jak potom reprezentovat, když funkce nemůže vrátit žádnou hodnotu? Třeba když žádná není... Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 23 / 26
Třída Optional public final class Optional<T> { public static<t> Optional<T> empty() {...} public static<t> Optional<T> of(t value) {...} public static<t> Optional<T> ofnullable(t value) {..}... } Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 24 / 26
Třída Optional - metody filter map flatmap ispresent ifpresent get orelseget Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 25 / 26
Třída Optional - metody filter map flatmap ispresent ifpresent get orelseget Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 25 / 26
Třída Optional - metody filter map flatmap ispresent ifpresent get orelseget Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 25 / 26
Třída Optional - metody filter map flatmap ispresent ifpresent get orelseget Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 25 / 26
Třída Optional - metody filter map flatmap ispresent ifpresent get orelseget Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 25 / 26
Třída Optional - metody filter map flatmap ispresent ifpresent get orelseget Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 25 / 26
Třída Optional - metody filter map flatmap ispresent ifpresent get orelseget Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 25 / 26
Třída Optional - ukázka kódu String version = computer.flatmap(computer::getsoundcard).flatmap(soundcard::getusb).map(usb::getversion) http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 26 / 26
@Nonnull a @Nullable anotace Anotace @Nonnull a @Nullable umožňují označit proměnné jestli mohou být null. Společně s Optional nám to umožní zvýšit kvalitu kódu. Anotace jsou popsány v JSR 305: Annotations for Software Defect Detection. Ondřej Hrstka, 2015 A0B36PR2 Přednáška 13: Java 8 27 / 26