JavaRush /Blog Java /Random-PL /Nieproste, proste przepływy
Oleg Savenko
Poziom 41
Одесса

Nieproste, proste przepływy

Opublikowano w grupie Random-PL
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

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ę, filterprzefiltrowaliś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, countktó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, countobliczył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:
  1. Z pliku źródłowego wczytujemy wszystkie słowa na listę.

  2. Następnie wykonujemy następujący wiersz

    Optional<String> rezult = list.stream()
    				.filter(w->w.length()>6)
    				.reduce((w1,w2)->w1+", "+w2);
  3. result.get()napisz do pliku.

Oto ciekawe rozwiązanie wykorzystujące wątki. Filtr przefiltrował i za pomocą funkcji redukcji i wyrażenia regularnego wygenerowano wymagany ciąg znaków.

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.
Do głównego zadania, jakim jest zapisanie liczb w ciągu znaków oddzielonych spacjami, do dalszego zapisu do pliku sugeruję użycie strumienia, będzie to wyglądało tak:
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:
  1. 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ść.
  2. 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.
  3. 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.
PS . Żartowałem o WSZYSTKICH PROBLEMACH. Polecamy: Profesjonalna biblioteka Java. Tom 2 Zaawansowane narzędzia programistyczne. Kay Horstmann. Mam dziesiąte wydanie.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION