Z´ aklady programovan´ı 4 (Java)
Stream API Petr Krajˇca
Katedra informatiky Univerzita Palack´eho v Olomouci
Petr Krajˇ ca (UP)
KMI/ZP4JV
5. listopad, 2014
1 / 10
Stream API Java 8 nov´y pˇr´ıstup k pr´aci s kolekcemi nejsou to kolekce jako takov´e (pouze obaluj´ı data) koˇreny ve funkcion´aln´ım programov´an´ı l´ın´e vyhodnocov´an´ı podpora implicitnˇe paraleln´ıho zpracov´an´ı sv´ym zp˚ usobem DSL (postaven´y na konceptu fluent interface)
Petr Krajˇ ca (UP)
KMI/ZP4JV
5. listopad, 2014
2 / 10
Lambda v´yrazy Lambdas are relegated to relative obscurity until Java makes them popular by not having them. -- James Iry, A Brief, Incomplete, and Mostly Wrong History of Programming Languages funkcion´ aln´ı rozhran´ı = rozhran´ı deklaruj´ıc´ı jednu abstraktn´ı metodu public interface Procedure { public void invoke(Object arg); } Procedure p = new Procedure() { public void invoke(Object arg) { System.out.println("hello " + arg); } }; Petr Krajˇ ca (UP)
KMI/ZP4JV
5. listopad, 2014
3 / 10
Lambda v´yrazy z pohledu program´atora jsou lambda v´yrazy „syntaktick´y cukr” (argumenty) -> vyraz (Typ1 arg1, Typ2 arg2, ...) -> vyraz Procedure p = (Object arg) -> System.out.println(arg); Procedure p = (arg) -> System.out.println(arg); Procedure p = arg -> System.out.println(arg); Procedure p = arg -> { System.out.println(arg); // pokud se ma vratiti hodnota: return "XXX"; }
Petr Krajˇ ca (UP)
KMI/ZP4JV
5. listopad, 2014
4 / 10
Lambda v´yrazy lze pouˇz´ıt i odkazy na metody, oper´ator :: Trida::statickaMetoda Trida::metoda objekt::metoda Trida::new (konstruktor) class Foo { public static void main(String[] args) { Procedure p = Foo::bar; p.invoke("123"); } public static void bar(Object arg) { System.out.println(arg); } } Petr Krajˇ ca (UP)
KMI/ZP4JV
5. listopad, 2014
5 / 10
Pˇredchystan´e funkcion´aln´ı rozhran´ı bal´ıˇcek java.util.function Supplier
– metoda T get() Consumer – metoda void accept(T t) Predicate – metoda boolean test(T t) Function – metoda R apply(T t) BiFunction – metoda R apply(T t, U u) BiOperator – metoda T apply(T t1, T T2) ...
Petr Krajˇ ca (UP)
KMI/ZP4JV
5. listopad, 2014
6 / 10
Probl´em s null v kolekc´ıch Map<String, String> foo = new HashMap<>(); foo.put("a", null); foo.get("a"); // ==> null foo.containsKey("a"); // ==> true Nov´a tˇr´ıda Optional obaluj´ıc´ı v´ysledky. Optional o = ... o.isPresent() // predikat o.isPresent(Consumer c) // provedeni consumeru o.orElse(T t) // nahradni hodnota o.orElseGet(Supplier s) // ziska hodnotu odjinud
Petr Krajˇ ca (UP)
KMI/ZP4JV
5. listopad, 2014
7 / 10
Stream API Vytvoˇren´ı streamu z hodnot: Stream.of(1, 2, 3) z pole: Stream.of(fooArray) z kolekce: foo.stream() z jin´eho streamu: stream.map, stream.filter, . . . Operace se streamy (1/2) stream.count() – vrac´ı poˇcet hodnot stream.filter(Predicate p) – ponech´a ve streamu pouze hodnoty splˇ nuj´ıc´ı dan´y predik´at stream.distinct() – odstran´ı duplicity (equals) stream.map(Function f) – aplikuje funkci na kaˇzdou hodnotu stream.forEach(Consumer c) – s kaˇzd´ym prvkem provede danou operaci stream.sorted(), stream.sorted(Comparator c) – setˇr´ıd´ı stream
Petr Krajˇ ca (UP)
KMI/ZP4JV
5. listopad, 2014
8 / 10
Stream API Operace se streamy (2/2) stream.findFirst() – vrac´ı prvn´ı prvek streamu (hodnota je typu Optional) stream.findAny() – vrac´ı jak´ykoliv prvek streamu (opˇet hodnota typu Optional) stream.allMatches(Predicate p) – vrac´ı true, pokud vˇsechny hodnoty odpov´ıdaj´ı predik´atu stream.anyMatch(Predicate p) – vrac´ı true, pokud alespoˇ n jedna hodnota odpov´ıd´a predik´atu stream.noneMatch(Predicate p) – vrac´ı true, pokud ani jedna hodnota neodpov´ıd´a predik´atu stream.max(Comparator c) – nejmenˇs´ı hodnota ve streamu stream.min(Comparator c) – nejvˇetˇs´ı hodnota ve streamu stream.limit(int n) – omez´ı d´elku streamu na n prvk˚ u stream.skip(int n) – pˇreskoˇc´ı prvn´ıch n prvk˚ u
Petr Krajˇ ca (UP)
KMI/ZP4JV
5. listopad, 2014
9 / 10
Stream API Konverze streamu na hodnoty metoda stream.collect(...) hotov´e ˇreˇsen´ı ve tˇr´ıde java.util.stream.Collectors Stream.of(employees).map(Employee::getName).iterator(); Stream.of(employees).map(Employee::getName).collect(Collectors.toList()); Stream.of(employees).map(Employee::getName).collect(Collectors.toSet()); Stream.of(employees).map(Employee::getName) .collect(Collectors.joining(",")); Stream.of(employees).collect(Collectors.groupingBy(Employee::getDept))); Stream.of(employees).map(Employee::getName).toArray(String[]::new); Paralelizace stream.parallel() – vrac´ı paraleln´ı stream; dalˇs´ı operace (napˇr. map, forEach mohou b´yt prov´adˇeny soubˇeˇznˇe)
Petr Krajˇ ca (UP)
KMI/ZP4JV
5. listopad, 2014
10 / 10