Jak nauczyć się Java Stream API [+5 Resources]

Strumień w Javie to sekwencja elementów, na których można wykonywać sekwencyjne lub równoległe operacje.

Może istnieć liczba „n” operacji pośrednich i wreszcie operacja końcowa, po której zwracany jest wynik.

Co to jest strumień?

Strumieniami można zarządzać za pomocą interfejsu Stream API, który został wprowadzony w Javie 8.

Wyobraź sobie Stream jako potok produkcyjny, w którym niektóre towary muszą zostać wyprodukowane, posortowane, a następnie zapakowane do wysyłki. W Javie towarami tymi są obiekty lub kolekcje obiektów, operacjami są produkcja, sortowanie i pakowanie, a potok to strumień.

Składnikami strumienia są:

  • Wejście wstępne
  • Operacje pośrednie
  • Obsługa terminala
  • Wynik końcowy

Przyjrzyjmy się niektórym cechom strumienia w Javie:

  • Strumień nie jest strukturą danych w pamięci; jest to raczej sekwencja tablic, obiektów lub kolekcji obiektów, na których działają określone metody.
  • Strumienie mają charakter deklaratywny, tzn. określasz, co należy zrobić, ale nie określasz, jak to zrobić.
  • Można je spożyć tylko raz, ponieważ nie są nigdzie przechowywane.
  • Stream nie modyfikuje oryginalnej struktury danych; wywodzi z niego tylko nową strukturę.
  • Zwraca wynik końcowy pochodzący z metody final w potoku.

Stream API a przetwarzanie kolekcji

Kolekcja to struktura danych w pamięci, która przechowuje i przetwarza dane. Kolekcje zapewniają struktury danych, takie jak zestaw, mapa, lista itp., służące do przechowywania danych. Z drugiej strony strumień to sposób na sprawne przesyłanie danych po ich przetworzeniu przez potok.

Oto przykład kolekcji ArrayList: –

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(0, 3);
        System.out.println(list);
    }
}

Output: 
[3]

Jak widać na powyższym przykładzie, można utworzyć kolekcję ArrayList, przechowywać w niej dane, a następnie operować na tych danych przy użyciu różnych metod.

Za pomocą strumienia można operować na istniejącej strukturze danych i zwracać nową, zmodyfikowaną wartość. Poniżej znajduje się przykład tworzenia kolekcji ArrayList i filtrowania jej za pomocą strumienia.

import java.util.ArrayList;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList();

        for (int i = 0; i < 20; i++) {
            list.add(i+1);
        }

        System.out.println(list);

        Stream<Integer> filtered = list.stream().filter(num -> num > 10);
        filtered.forEach(num -> System.out.println(num + " "));
    }
}

#Output

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 

W powyższym przykładzie strumień jest tworzony przy użyciu istniejącej listy, a lista jest iterowana w celu odfiltrowania wartości większych niż 10. Zauważ, że strumień niczego nie przechowuje, lista jest tylko iterowana, a wynik jest drukowany. Jeśli spróbujesz wydrukować strumień, zamiast wartości otrzymasz odwołanie do strumienia.

Praca nad Java Stream API

Java Stream API pobiera źródłową kolekcję elementów lub sekwencję elementów, a następnie wykonuje na nich operacje w celu uzyskania wyniku końcowego. Strumień to po prostu potok, przez który przechodzi sekwencja elementów i jest w jakiś sposób przekształcana.

Strumień można utworzyć z różnych źródeł, w tym:

  • Kolekcja, taka jak lista lub zestaw.
  • tablica.
  • Z plików i ich ścieżek za pomocą bufora.

Istnieją dwa rodzaje operacji wykonywanych w strumieniu: –

  • Operacje pośrednie
  • Operacje terminalowe

Operacje pośrednie a operacje terminalowe

Każda operacja pośrednia zwraca wewnętrznie nowy strumień, który przekształca dane wejściowe przy użyciu określonej metody. W rzeczywistości nic nie jest przemierzane; Zamiast tego jest przekazywany do następnego strumienia. Dopiero podczas operacji terminalowej strumień jest przemierzany w celu uzyskania pożądanego rezultatu.

Na przykład masz listę 10 liczb, które chcesz odfiltrować, a następnie zmapować na coś. Nie każdy element listy zostanie natychmiast przejrzany, aby uzyskać przefiltrowany wynik i zmapować go na coś innego. Zamiast tego zostaną sprawdzone poszczególne elementy, a jeśli spełnią warunek, zostaną zmapowane. Nowe strumienie dla każdego elementu.

Operacja na mapie zostanie przeprowadzona na pojedynczych elementach spełniających kryteria filtru, a nie na całej liście. A w czasie operacji terminala są one przeglądane i łączone w jeden wynik.

Po wykonaniu operacji terminalowej strumień jest zużywany i nie może być dalej używany. Musisz utworzyć nowy strumień, aby ponownie wykonać te same operacje.

źródło: The Bored Dev

Mając powierzchowne zrozumienie działania strumieni, przejdźmy do szczegółów implementacji strumieni w Javie.

# 1. Pusty strumień

Utwórz pusty strumień przy użyciu metody empty interfejsu Stream API.

import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        Stream emptyStream = Stream.empty();
        System.out.println(emptyStream.count());
    }
}

Output:
0

Tutaj, jeśli wydrukujesz liczbę elementów w tym strumieniu, otrzymasz 0 jako wynik, ponieważ jest to pusty strumień bez elementów. Puste strumienie są bardzo pomocne w unikaniu wyjątków zerowego wskaźnika.

#2. Transmisja strumieniowa z kolekcji

Kolekcje, takie jak Lists i Set, udostępniają metodę stream(), która umożliwia utworzenie strumienia z kolekcji. Utworzony strumień można następnie przemierzać, aby uzyskać efekt końcowy.

ArrayList<Integer> list = new ArrayList();

for (int i = 0; i < 20; i++) {
    list.add(i+1);
}

System.out.println(list);

Stream<Integer> filtered = list.stream().filter(num -> num > 10);
filtered.forEach(num -> System.out.println(num + " "));

#Output

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 

#3. Strumień z tablic

Metoda Arrays.stream() służy do tworzenia strumienia z tablicy.

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        String[] stringArray = new String[]{"this", "is", "newsblog.pl"};
        Arrays.stream(stringArray).forEach(item -> System.out.print(item + " "));
    }
}

#Output

this is newsblog.pl 

Możesz także określić początkowy i końcowy indeks elementów, z których chcesz utworzyć strumień. Indeks początkowy jest włącznie, podczas gdy indeks końcowy jest wyłączny.

String[] stringArray = new String[]{"this", "is", "newsblog.pl"};
Arrays.stream(stringArray, 1, 3).forEach(item -> System.out.print(item + " "));

Output:
is newsblog.pl

#4. Znajdowanie minimalnych i maksymalnych liczb za pomocą strumieni

Dostęp do maksymalnej i minimalnej liczby kolekcji lub tablicy można uzyskać za pomocą komparatorów w Javie. Metody min() i max() akceptują komparator i zwracają obiekt Opcjonalny.

Opcjonalny obiekt to obiekt kontenera, który może zawierać wartość inną niż null lub nie. Jeśli zawiera wartość różną od null, wywołanie na niej metody get() zwróci wartość.

import java.util.Arrays;
import java.util.Optional;

public class MinMax {
    public static void main(String[] args) {
        Integer[] numbers = new Integer[]{21, 82, 41, 9, 62, 3, 11};

        Optional<Integer> maxValue = Arrays.stream(numbers).max(Integer::compare);
        System.out.println(maxValue.get());

        Optional<Integer> minValue = Arrays.stream(numbers).min(Integer::compare);
        System.out.println(minValue.get());
    }
}

#Output
82
3

Zasoby edukacyjne

Teraz, gdy masz podstawową wiedzę na temat strumieni w Javie, oto 5 zasobów, które pomogą ci dobrze zorientować się w Javie 8:

# 1. Java 8 w akcji

Ta książka to przewodnik prezentujący nowe funkcje języka Java 8, w tym strumienie, wyrażenia lambda i programowanie w stylach funkcjonalnych. Częścią książki są również quizy i pytania sprawdzające wiedzę, które pomogą Ci odzyskać to, czego się nauczyłeś.

Możesz dostać tę książkę w formacie miękkiej oprawy, a także w formacie audiobooka na Amazon.

#2. Java 8 Lambdas: programowanie funkcjonalne dla mas

Ta książka została specjalnie zaprojektowana, aby nauczyć podstawowych programistów Java SE, w jaki sposób dodanie wyrażeń Lambda wpływa na język Java. Zawiera płynne wyjaśnienia, ćwiczenia z kodem i przykłady pozwalające opanować wyrażenia lambda języka Java 8.

Jest dostępny w formacie miękkiej oprawie i wydaniu Kindle na Amazon.

#3. Java SE 8 dla naprawdę niecierpliwych

Jeśli jesteś doświadczonym programistą Java SE, ta książka przeprowadzi Cię przez ulepszenia wprowadzone w Javie SE 8, interfejs Stream API, dodanie wyrażeń lambda, ulepszenia programowania współbieżnego w Javie oraz niektóre funkcje Javy 7, których większość ludzi nie zna. nie wiem o.

Jest dostępny tylko w formie papierowej na Amazon.

#4. Naucz się programowania funkcyjnego w języku Java z lambdami i strumieniami

Ten kurs Udemy omawia podstawy programowania funkcyjnego w Javie 8 i 9. Wyrażenia lambda, odwołania do metod, strumienie i interfejsy funkcjonalne to pojęcia, na których koncentruje się ten kurs.

Zawiera również garść zagadek Java i ćwiczeń związanych z programowaniem funkcyjnym.

#5. Biblioteka klas Javy

Java Class Library jest częścią Core Java Specialization oferowanej przez Coursera. Nauczy Cię, jak pisać kod bezpieczny dla typów przy użyciu Java Generics, zrozumieć bibliotekę klas składającą się z ponad 4000 klas, jak pracować z plikami i radzić sobie z błędami czasu wykonywania. Istnieją jednak pewne warunki wstępne, aby wziąć udział w tym kursie:

  • Wprowadzenie do Javy
  • Wprowadzenie do programowania obiektowego w Javie
  • Hierarchie zorientowane obiektowo w Javie

Ostatnie słowa

Java Stream API i wprowadzenie funkcji Lambda w Javie 8 uprościło i ulepszyło wiele rzeczy w Javie, takich jak iteracja równoległa, interfejsy funkcjonalne, mniej kodu itp.

Jednak strumienie mają pewne ograniczenia; ich największym ograniczeniem jest to, że można je spożyć tylko raz. Jeśli jesteś programistą Java, wymienione powyżej zasoby mogą pomóc ci w bardziej szczegółowym zrozumieniu tych tematów, więc koniecznie je przejrzyj.

Możesz także chcieć wiedzieć o obsłudze wyjątków w Javie.