Z każdą nową wersją Javy staje się ona coraz bogatsza. Chociaż większość bogactwa kryje się we wcześniejszych wersjach, język jest nadal udoskonalany, zarówno pod względem metodologii, jak i wdrożenia. Kolekcje w Javie nie są wyjątkiem. Podstawowy framework kolekcji pojawił się w J2SE 1.2 i nadal ewoluował, przechodząc zmiany, które bardziej cieszyły niż rozczarowywały. Wraz z wydaniem JDK 5 kolekcje stały się wygodniejsze, szybsze i łatwiejsze w obsłudze. Doprowadziło to do tego, że programiści zaczęli intensywniej je eksploatować. Opracowano pewne wzorce pracy z nimi, które bez wątpienia są skuteczne. Ale dzięki JDK 8 kolekcje znów stały się lepsze, a dzięki wątkom stały się jeszcze lepsze. Oczywiście w związku z tym, że kolekcję można reprezentować w formie strumieni, zmieni się także metodologia pracy z nimi. Dlatego chcę pokazać, jak znane i zrozumiałe rozwiązania z kolekcjami stają się jeszcze prostsze.
- Przykład 1. To nie może być prostsze
- Przykład 2. Znajdź na liście parzyste wartości i wyświetl je w konsoli
- Przykład 3. Policzmy, ile słów na liście ma długość 5 znaków
- Przykład 4. Wydrukuj unikalne słowa
- Przykład 5. Długie słowa
- Przykład 6. Słowa z liczbami
- Przykład 7. Wybieranie liczb
Przykład 1. To nie może być prostsze
Zacznijmy oczywiście od najprostszej rzeczy, przejrzyjmy wszystkie elementy kolekcji i pokażmy wszystkie elementy.// создадим и заполним список
List<Integer> list = new ArrayList<>();
Collections.addAll(list, 1, 5, 6, 11, 3, 15, 7, 8);
// а теперь
// быстрый for по всем elementм, только для коллекций
for (Integer i:list){
System.out.println(i);
}
//но мы уже живем в JDK 8
//а значит нужно так
list.stream().forEach(System.out::println);
Jak zauważyłeś, istnieje nowa składnia, która moim zdaniem, jako nowicjusza w Javie, jest znacznie prostsza. A więc co widać w nowej składni:
берем_список(list).превращаем_в_поток(stream).перебираем_все_элементы(forEach)(тут_интуитивно_понятно)
System.out::println
— link do metody statycznej, która wysyła ciąg znaków do konsoli Zamiast linku do metody statycznej, możesz użyć nieco innego, mniej jasnego wpisu:
list.stream().forEach(i -> System.out.println(i));
W tym wpisie zastosowano wyrażenia lambda. I tak, aby nauczyć się pracować ze strumieniami, będziesz musiał nauczyć się wyrażeń lambda - są cudowne. Dalej nie będę pokazywał jak pracować ze zbiorami wykorzystując wyłącznie strumienie, opierając się na tym, że w trakcie kursu zapoznałeś się z tradycyjnymi metodami.
Przykład 2. Znajdź na liście parzyste wartości i wyświetl je w konsoli
list.stream().filter(i -> i%2==0).forEach(System.out::println);
Cały problem został rozwiązany w jednej linijce. Mam nadzieję, że będzie Ci się podobać praca w jednej linii. Stosując tę metodę, filter
przefiltrowaliśmy strumień i wypuściliśmy to, co pozostało, na konsolę. Filtr to bardzo potężna rzecz, która może pomóc w najbardziej nieoczekiwanych przypadkach. Wykażmy się kreatywnością i zmieńmy uwarunkowania problemu. Na przykład musimy policzyć, ile liczb parzystych znajduje się na liście:
long count = list.stream().filter(i -> i%2==0).count();
I znowu w jednym wierszu. W jakiś sposób wszystko wydaje się proste. W filtrze zastosowaliśmy wyrażenie lambda, umieszczając w ten sposób w nowym strumieniu tylko liczby parzyste, a następnie zastosowaliśmy do nowego strumienia, count
który zliczył, ile elementów znajduje się w nowym strumieniu.
Przykład 3. Policzmy, ile słów na liście ma długość 5 znaków
Bawiliśmy się liczbami całkowitymi, teraz pobawimy się słowami.List<String> list = new ArrayList<>();
Collections.addAll(list, "разые", "слова", "интересные", "I", "Nie", "Bardzo");
System.out.println(list.stream().filter(w -> w.length() == 5).count());
Ponownie użyliśmy filtra. W filtrze za pomocą wyrażenia lambda wyświetlił się nowy strumień, a następnie, co zrozumiałe, count
obliczyłem, ile elementów znajduje się w nowym strumieniu.
Przykład 4. Wydrukuj unikalne słowa
Znane zadanie, gdy wczytujemy wiele różnych słów do zbioru z pliku, a teraz potrzebujemy tylko unikalnych.List<String> list = new ArrayList<>();
Collections.addAll(list, "Wasya", "Таня", „Olya”, "Wasya", „Olya”, "Сергей");
list.stream().distinct().forEach(System.out::println);
Główna akcja została wykonana na strumieniu przy użyciu distinct
. Następnie proponuję przyjrzeć się niektórym naszym zadaniom z kursu z wykorzystaniem wątków
Przykład 5. Długie słowa
Na 9. poziomie Java Core, na wykładzie 11 pojawia się ciekawy problem, polegający na tym, że w File2 należy wpisać słowa oddzielone przecinkami, których długość jest ściśle większa niż 6. Nieważne jaki ogród ogrodzisz, Proponuję następujące rozwiązanie:-
Z pliku źródłowego wczytujemy wszystkie słowa na listę.
-
Następnie wykonujemy następujący wiersz
Optional<String> rezult = list.stream() .filter(w->w.length()>6) .reduce((w1,w2)->w1+", "+w2);
-
result.get()
napisz do pliku.
Przykład 6. Słowa z liczbami
Wpisz wszystkie słowa zawierające liczby, na przykład a1 lub abc3d, oddzielone spacją w pliku File2. Jest to również warunek z naszej książki problemów, jak się domyślacie, rozwiązanie jest proste.Optional<String> rezult = list.stream()
.filter(w->w.matches(".*?\\d+.*?"))
.reduce((w1,w2)->w1+" "+w2);
Przefiltrowaliśmy strumień za pomocą wyrażenia regularnego, a następnie redukcji i wyrażenia lambda. Tyle wspólnego z poprzednim zadaniem.
Przykład 7. Wybieranie liczb
Całe zadanie brzmi tak:- Przeczytaj 2 nazwy plików z konsoli.
- Wyprowadź do drugiego pliku wszystkie liczby znajdujące się w pierwszym pliku.
- Liczby oddzielane są spacjami.
- Zamknij strumienie.
Optional<String> rezult = list.stream().filter(w->w.matches("\\d+"))
.reduce((w1,w2)->w1+" "+w2);
System.out.println(rezult.get());
Używając wątków, problem rozwiązuje się w bardzo prosty sposób. Ale oto i porównaj to rozwiązanie z dwoma poprzednimi samodzielnie. Kończąc artykuł, chcę ci się przyznać: chłopaki, oszukiwałem, wybierając przykłady. Faktem jest, że wybrałem najprostsze przykłady, aby pokazać nieznany temat za pomocą znanych problemów. Oczywiście wątki służą zarówno do prostych, jak i bardziej złożonych zadań. Jednak jak podkreślił Horstman w swojej książce: „Przepływy danych działają na zasadzie „co, a nie jak to zrobić”, co oznacza, że wiele wcześniej złożonych zadań może stać się prostszych. Nie wiem jak Wam, ale mnie te flow przypadły mi do gustu, mam nadzieję, że Was nie zniechęciłam do ich nauki. I wyjaśnię jeszcze jedną rzecz:
- Nie chciałem uczyć czytelnika, jak korzystać ze strumieni w kolekcjach; nie jestem aż tak doświadczonym nauczycielem. Chciałam Wam pokazać, że wątki są proste i bardzo ciekawe! Ogólnie rzecz biorąc, jest to konieczność.
- Im lepiej rozumiem przepływy, tym częściej widzę problemy tam, gdzie rozwiązują wszystkie problemy z podręcznika, co oznacza, że przepływy nie zostały wymyślone na próżno.
- Strumienie są nie tylko łatwe w obsłudze, ale mają też ważną zaletę – podczas pracy z dużą ilością danych strumienie są często bardziej produktywne.
GO TO FULL VERSION