API STREAM WYRAŻENIA LAMBDA

Podobne dokumenty
Programowanie w języku Java. Kolekcje

Java Collections Framework

Kolekcje. Na podstawie:

java.util.* :Kolekcje Tomasz Borzyszkowski

Programowanie Obiektowe (Java)

Podstawy otwartych języków programowania Przechowywanie danych

Kolekcje - pakiet Java Collections Framework

Kolekcja (kontener) to po prostu obiekt, który grupuje wiele elementów w jeden twór.

PROGRAMOWANIE FUNKCYJNE

Kolekcje - pakiet Java Collections Framework

Realizacja ekstensji klasy. Paulina Strzelecka, Tomasz Roszkowski

Wydział Fizyki i Informatyki Stosowanej, Uniwersytetu Łódzkiego Łódź. Java podstawy języka, wykład 4 1

GUI - projektowanie interfejsów cz. II

Języki i metody programowania Java INF302W Wykład 3 (część 2)

Kolekcje mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

Tworzenie aplikacji w języku Java

Programowanie obiektowe

Lista, Stos, Kolejka, Tablica Asocjacyjna

Platformy Programistyczne Podstawy języka Java

dr inż. Piotr Czapiewski Tworzenie aplikacji w języku Java Laboratorium 1

Kolekcje. object that groups multiple elements into a single unit

WIELOWĄTKOWOŚĆ. Waldemar Korłub. Platformy Technologiczne KASK ETI Politechnika Gdańska

Java niezbędnik programisty spotkanie nr 8. Kolekcje c.d.

Programowanie w Javie - wykład 14 Podstawy programowania funkcyjnego

Język JAVA podstawy. Wykład 4, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Programowanie i projektowanie obiektowe

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Interfejsy w Java. Przetwarzanie równoległe. Wątki.

Laboratorium z przedmiotu Programowanie obiektowe - zestaw 04

Programowanie w Javie wykład 15 Elementy programowania funkcyjnego cd.

Wątki. Definiowanie wątków jako klas potomnych Thread. Nadpisanie metody run().

Comparable<Klasa_uzytkownika>

Klasy abstrakcyjne i interfejsy

Kolekcje w Javie cz. 1

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Kurs programowania. Wykład 9. Wojciech Macyna

Programowanie obiektowe

Programowanie obiektowe

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

Dawid Gierszewski Adam Hanasko

import java.util.*; public class ListExample { public static void main(string args[]) { List<String> lista1= new ArrayList<String> ();

Język Java część 2 (przykładowa aplikacja)

Programowanie w Javie- wykład 12 Kolekcje (zbiory)

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Java: interfejsy i klasy wewnętrzne

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

1 Atrybuty i metody klasowe

Wstęp do ruby dla programistów javy

Wykład 2 Składnia języka C# (cz. 1)

Java SE Laboratorium nr 7. Temat: Kolekcje

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Java. Wykład. Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ

JDK 8 WPROWADZENIE DO WYBRANYCH ZAGADNIEŃ

WSNHiD, Programowanie 2 Lab. 2 Język Java struktura programu, dziedziczenie, abstrakcja, polimorfizm, interfejsy

Algorytmy i Struktury Danych. Anna Paszyńska

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

Programowanie. programowania. Klasa 3 Lekcja 9 PASCAL & C++

Kompletna dokumentacja kontenera C++ vector w -

Dokumentacja do API Javy.

Programowanie obiektowe

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

PHP: bloki kodu, tablice, obiekty i formularze

Programowanie w Javie- wykład 11 Kolekcje (listy)

Typy sparametryzowane

TYPY GENERYCZNE (GENERICS)

Podstawy programowania. Podstawy C# Tablice

Swift (pol. jerzyk) nowy język programowania zaprezentowany latem 2014 r. (prace od 2010 r.)

Polimorfizm. dr Jarosław Skaruz

Współbieżność w środowisku Java

Java. Michał Wójcik.

Programowanie w języku Java 7 z biblioteką SWING

Programowanie obiektowe

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Programowanie obiektowe

Programowanie i struktury danych

Instrukcja 2 Laboratorium z Podstaw Inżynierii Oprogramowania

Programowanie w C++ Wykład 6. Katarzyna Grzelak. 1 kwietnia K.Grzelak (Wykład 6) Programowanie w C++ 1 / 43

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Podstawy Programowania Obiektowego

Laboratorium z przedmiotu: Inżynieria Oprogramowania INEK Instrukcja 7

Kurs WWW. Paweł Rajba.

Klasy abstrakcyjne, interfejsy i polimorfizm

Języki i techniki programowania Ćwiczenia 2

Wykład 5 Wybrane zagadnienia programowania w C++ (c.d.)

KOLEKCJE JAVY API: NAJPROSTSZE PODSTAWY

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Programowanie obiektowe

Wykład 3 Składnia języka C# (cz. 2)

KOTLIN. Język programowania dla Androida

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Programowanie w C++ Wykład 7. Katarzyna Grzelak. 23 kwietnia K.Grzelak (Wykład 7) Programowanie w C++ 1 / 40

Wykład 4. Klasa List Kolejki Stosy Słowniki

Aplikacje w Javie- wykład 11 Wątki-podstawy

Java niezbędnik programisty spotkanie nr 9. Java 2 Platform, Standard Edition 5.0

Tworzenie aplikacji w języku Java

Programowanie obiektowe i zdarzeniowe

Wprowadzenie db4o - podstawy db4o - technikalia Przydatne wiadomości. Wprowadzenie. db4o. Norbert Potocki. 1 czerwca Norbert Potocki db4o

Dziedziczenie. Tomasz Borzyszkowski

Transkrypt:

Wykorzystano fragmenty wykładów M. Piotrowskiego i M. Wójcika KOLEKCJE API STREAM WYRAŻENIA LAMBDA Waldemar Korłub Platformy Technologiczne KASK ETI Politechnika Gdańska

2 Kolekcje

Kolekcje 3 Kolekcja kontener, obiekt grupujący elementy Collection Framework narzędzia służące do reprezentacji i manipulacji kolekcjami: interfejsy abstrakcyjne typy reprezentujące kolekcje, implementacje konkretne implementacje interfejsów, algorytmy metody narzędziowe pozwalające na wyszukiwanie, sortowanie, permutowanie itd. n mogą być wykorzystywane niezależnie od implementacji kolekcji

Interfejsy kolekcji 4 Collection najbardziej uniwersalny interfejs kolekcji brak ograniczeń typu elementów, powtarzalności lub kolejności, Set nie zawiera duplikatów elementów, List sekwencja elementów o określonej kolejności, może zawierać duplikaty, Queue sekwencja elementów (np. FIFO) lub posortowane elementy (kolejki priorytetowe),

Interfejsy kolekcji 5 Map odwzorowanie par klucz à wartość nie może zawierać powtórzonych kluczy, jeden klucz może wskazywać na jedną wartość, SortedSet zawiera posortowane elementy SortedMap sortowanie wzgle dem kluczy

6 Podstawowe operacje: przeglądanie kolekcji Interfejs List obsługuje indeksowanie elementów, np.: for(int i = 0; i < list.size(); ++i){ list.get(i); } for-each: for (Object o: collection) { /*...*/ } nie należy usuwać elementów z kolekcji, po której iterujemy (ConcurrentModificationException), działa również dla tablic; iterator: pozwala na usuwanie elementów n usuwać należy jedynie za pośrednictwem interfejsu iteratora! Iterator it = c.iterator(); while (it.hasnext()) { Object element = it.next(); if (/*...*/) { it.remove(); } }

Podstawowe operacje 7 Bulk operations operacje na wielu elementach kolekcji containsall, addall, removeall, retainall, clear Konwersja na tablice: Object[] toarray() zwraca kolekcję jako tablicę elementów typu Object, Type[] toarray(new Type[0]) zwraca kolekcję jako tablicę elementów typu Type

Sortowanie elementów kolekcji 8 Collections.sort(List list) sortowanie listy elementów typu Comparable Interfejs Comparable: pozwala na automatyczne sortowanie, int compareto(t other) zwracane wartości: n <0 gdy this mniejszy od other n 0 gdy this i other są równe n >0 gdy this większy od other

Sortowanie elementów kolekcji 9 boolean equals() metoda zdefiniowana w klasie Object (wszystkie klasy dziedziczą po Object) sprawdza czy obiekty są równe Gdy equals(other) zwraca true, metoda compareto(other) powinna zwracać 0! int hashcode() Jeśli nadpisujemy metodę equals() zawsze należy nadpisać również metodę hashcode() Gdy equals(other) zwraca true, metody hashcode() obu obiektów powinien zwracać tę samą wartość Wykorzystywana przez HashSet, HashMap itd.

Sortowanie elementów kolekcji 10 Nie wszystkie klasy dziedziczą po Comparable Collections.sort(List list, Comparator comp) Comparator<T> określa zasady porównywania elementów Jedna metoda: int compare(t o1, T o2) Comparator<String> comp = new Comparator<String>() { @Override public int compare(string o1, String o2) { return o1.length() - o2.length(); } };

Wybrane implementacje kolekcji 11 Interfejs Set: HashSet implementacja hash mapy, brak sortowania i stałej kolejności elementów, TreeSet implementacja struktury drzewiastej, zapewnia sortowanie, LinkedHashSet implementacja w postaci hash mapy i listy dwukierunkowej, zapewnia kolejnośc elementów; Interfejs List: ArrayList implementacja dynamicznie rozszerzalnej tablicy, LinkedList implementacja listy dwukierunkowej;

Wybrane implementacje kolekcji 12 Interfejs Queue: LinkedList, PriorityQueue implementacja kopca, zapewnia sortownie; Interfejs Map: HashMap brak sortowania, TreeMap sortowanie według kluczy, LinkedHashMap zachowana kolejność dodawania elementów.

Złożoność operacji 13 Kolekcja Dostęp losowy Wyszukiwanie Dodawanie ArrayList O(1) O(n) O(n) LinkedList O(n) O(n) O(1) HashSet O(1) O(1) O(1) HashMap O(1) O(1) O(1) TreeMap O(log(n)) O(log(n)) O(log(n)) PriorityQueue O(n)* O(n) O(log(n)) * tylko za pośrednictwem iteratora

Zewnętrzne biblioteki 14 Guava HashBiMap n Dwukierunkowe odwzorowanie MultiSet n Pozwala na duplikaty ArrayListMultiMap n Pozwala na duplikaty kluczy RangeSet n Zbiór rozłącznych niepustych zakresów Fastutil Eclipse Collections JCTools

API Stream 15 Dodatkowe operacje na kolekcjach umożliwia API Stream Lecz najpierw

16 Wyrażenia lambda

Wyrażenia lambda: motywacje Rozszerzenie języka o elementy programowania funkcyjnego, m.in.: Domknięcia Currying częściowa aplikacja funkcji Mapowanie, filtrowanie, redukcja Łatwość zrównoleglania kodu funkcyjnego Zwięzła składnia Wygoda użycia w połączeniu z API Stream

Wyrażenia lambda: realizacja Wprowadzone w wersji SE8 (marzec 2014) Zdefiniowane w kategoriach programowania obiektowego Nie stanowią wyłomu w obiektowości języka Nie są samodzielnym elementem języka Dają wygodniejszą składnię do wykonywania operacji obiektowych Zintegrowane w wielu miejscach w bibliotece standardowej, w szczególności w API Stream

Zwięzłość Przed wyrażeniami lambda: b.addactionlistener( new ActionListener() { @Override public void actionperformed(actionevent event) { handleevent(event); } }); Obecnie: b.addactionlistener(event -> handleevent(event));

Zwięzłość Przed: new Thread(new Runnable() { @Override public void run() { doinbackground(); } }); Obecnie: new Thread(() -> doinbackground());

Interfejsy funkcyjne Koncepcja wprowadzona w SE8 na potrzeby wyrażeń lambda Interfejsy posiadające pojedynczą metodę abstrakcyjną Instancje anonimowych klas wewnętrznych, implementujących interfejs funkcyjny, mogą zostać zastąpione wyrażeniem lambda

Podstawowa składnia Instancje anonimowych klas wewnętrznych: new InterfejsFunkcyjny() { @Override public ReturnType method(argumenty) { /*ciało*/ } }; Zastępowane przez wyrażenie lambda: (argumenty) -> {/*ciało*/}

Przykład Komparator: new Comparator<String>() { @Override public int compare(string s1, String s2){ return (s1.length() - s2.length()); } }; Komparator jako wyrażenie lambda: (String s1, String s2) -> { return (s1.length() - s2.length()); }

Cukier (składniowy) Typy argumentów po lewej stronie operatora -> są zazwyczaj zbędne Najczęściej mogą być wywnioskowane z deklaracji metody w interfejsie funkcyjnym Jeśli występuje pojedynczy argument, nawiasy () są opcjonalne Jeśli ciało składa się z pojedynczego wyrażenia, nawiasy {} są opcjonalne Słowo kluczowe return również jest opcjonalne

Przykład Komparator: new Comparator<String>() { @Override public int compare(string s1, String s2){ return (s1.length() - s2.length()); } }; Komparator jako wyrażenie lambda: (String s1, String s2) -> { return (s1.length() - s2.length()); } Z pominięciem elementów opcjonalnych: (s1, s2) -> s1.length() - s2.length()

Lambda a obiektowość Wyrażenia lambda są zdefiniowane w kategoriach programowania obiektowego Jakiego typu jest wyrażenie lambda? à typ interfejsu funkcyjnego, który implementuje Wiele sytuacji wymaga typowych interfejsów funkcyjnych

Typowe interfejsy funkcyjne: java.util.function Predicate<T> wejście: T, wyjście: boolean public interface Predicate<T> { boolean test(t t); } Function<T, R> wejście: T; wyjście: R Consumer<T> wejscie: T; wyjście: void Supplier<T> wejście: brak; wyjście: T BinaryOperator<T> wejście: T, T; wyjście: T

Zmienne typu interfejsu funkcyjnego Skoro znamy typ wyrażenia lambda, możemy przypisać je do zmiennej jak każdą instancję implementującą dany interfejs Runnable r = () -> doinbackground(); Thread thread = new Thread(r); Comparator<String> comparator = (s1, s2) -> s1.length() - s2.length(); Arrays.sort(array, comparator); Function<String, Integer> len = s -> s.length(); len.apply("platformy technologiczne");

Currying częściowe wiązanie parametrów Dwuargumentowe wyrażenie lambda: BiPredicate<String, String> startwithsimple = (letter, str) -> str.startswith(letter); Currying wymaga rozdzielenia parametrów na osobne wyrażenia lambda: Function<String, Predicate<String>> startswith = letter -> str -> str.startswith(letter); Związanie wartości pierwszego argumentu: Predicate<String> startswithp = startswith.apply("p"); Związanie wartości drugiego argumentu i wywołanie: boolean flag = startswithp.test("platformy");

Zasięgi, dostęp do zmiennych Wyrażenie lambda nie wprowadza nowego zasięgu Słowo kluczowe this odnosi się do klasy zewnętrznej, nie do instancji anonimowej klasy wewnętrznej Nie występuje KlasaZewnetrzna.this Można odwoływać się do pól klasy zewnętrznej Można odwoływać się do zmiennych lokalnych oznaczonych słowem kluczowym final Można odwoływać się do zmiennych lokalnych, które pozostają niezmienne, nawet jeśli nie posiadają słowa kluczowego final (ang. effectively final)

31 API Stream

API Stream Programowanie funkcyjne to nie tylko wyrażenia lambda Map Filter Reduce API Stream (SE8) wprowadza zestaw interfejsów pozwalających na pisanie kodu w duchu programowania funkcyjnego z użyciem wyrażeń lambda

API Stream prosty przykład Proceduralnie: for(integer i: list){ System.out.print(i); } API Stream: list.stream().foreach(i -> System.out.println(i)); pozyskanie strumienia wyrażenie lambda

API Stream prosty przykład Wywołanie metody stream() opcjonalne, jeśli chcemy użyć tylko foreach() Jeśli ciało wyrażenia lambda ogranicza się do wywołania metody o liście argumentów identycznej jak lista argumentów wyrażenia, to można je zastąpić referencją na metodę, np.: Lambda: i -> System.out.println(i) Referencja: System.out::println Wypisanie zawartości listy na konsolę: list.foreach(system.out::println);

Pozyskiwanie strumieni Z kolekcji: Collection<String> collection = /*...*/ Stream<String> stream = collection.stream(); Z tablicy, zbioru obiektów: Stream.of(T...) Z wyrażenia regularnego: Pattern.compile(",").splitAsStream("Waldemar,Korłub,KASK,ETI"); Z pliku: Files.lines(Paths.get("katalog", "plik.txt")) buduje ścieżkę do pliku z uwzględnieniem specyfiki systemu operacyjnego, np.: \ dla Windowsa; / dla UNIXa

Podstawowe metody foreach(consumer) map(function) filter(predicate) findfirst() findany() collect(collectors.tolist()) sorted()/sorted(comparator) skip(long) limit(long) count()

Złożony przykład #1 List<String> names = Files.lines(Paths.get("nazwiska.txt")) filtrowanie: zaczyna się na K mapowanie: na duże litery bez duplikatów.filter(s -> s.startswith("k")).map(string::touppercase).distinct().sorted().collect(tolist()); posortowane wyniki operacji w postaci listy

Złożony przykład #2a 38 class Developer { String name; String city; int age; List<String> languages; } /*...gettery i inne metody...*/

Złożony przykład #2b 39 List<Developer> developers = /*...*/ strumień deweloperów double avgage = developers.stream().filter(dev -> dev.getcity().equals("gdańsk")).maptoint(dev -> dev.getage()).average().orelse(0); 25 31 38 23 43 obliczenie średniej może się nie udać zwraca 0, jeśli średnia nie występuje strumień liczb

Złożony przykład #2c 40 strumień deweloperów List<String> languages = developers.stream().map(developer::getlanguages) strumień zawierający listy języków List<String> Java C Ruby List<String> C C++ List<String> Java C# Perl.flatMap(Collection::stream) strumień nazw języków Java C Ruby C C++ Java C# Perl.distinct().sorted().collect(toList());

Grupowanie elementów 41 Map<String, List<Developer>> devsbycity = developers.stream().collect(groupingby(developer::getcity)); kolektor grupujący Klucz (String) Wartość (List<Developer>) Gdańsk Wrocław Warszawa

Operacje pośrednie i terminalne 42 Operacje pośrednie Zwracają kolejny strumień n np.: filter, map, sorted Odroczone wykonanie (ang. lazy execution) n Nie wykonują operacji dopóki nie nastąpi wywołanie metody terminalnej Operacje terminalne Przetwarzają dane w chwili wywołania n np.: collect, reduce, foreach Powodują wykonanie wszystkich wcześniejszych operacji pośrednich

Zrównoleglenie Kolekcja liczb: List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); Przetwarzanie sekwencyjne: list.stream(). map(n -> Integer.toString(n * 2) + " "). foreach(system.out::print); //2 4 6 8 10 Przetwarzanie równoległe: list.parallelstream(). map(n -> Integer.toString(n * 2) + " "). foreach(system.out::print); //4 2 10 8 6

Parallel stream 44 Oparty na frameworku Fork/Join (Java SE7) Domyślnie wykorzystuje pulę wątków ForkJoinPool.commonPool() liczba_wątków_puli = liczba_rdzeni 1 Wykorzystuje jako watek roboczy również wątek, w którym wywołano.parallelstream() liczba_wątków_roboczych = liczba_rdzeni Wywołania.parallelStream() z różnych miejsc aplikacji domyślnie używają tej samej puli wątków! Uwaga na zagładzanie zadań

Parallel stream własna pula wątków 45 Możliwe jest zdefiniowanie własnej puli wątków: ForkJoinPool custompool = new ForkJoinPool(4); custompool.submit( () -> devs.parallelstream().foreach(/*...*/)); Jeśli strumień zwraca wartość: ForkJoinTask<Double> task = custompool.submit( () -> developers.parallelstream().maptoint(developer::getage).average().orelse(0)); Double avg = task.get(); // wywołanie blokujące

Parallel stream własna pula wątków 46 Można również użyć klasy CompletableFuture, np.: CompletableFuture<Double> future = CompletableFuture.supplyAsync( () -> developers.parallelstream().maptoint(developer::getage).average().orelse(0), new ForkJoinPool(4)); Double avg = future.get(); CompletableFuture pozwala na budowanie sekwencji powiązanych ze sobą współbieżnych zadań

47 Pytania?