Mam problem ze zrozumieniem Stream
interfejsu w Javie 8, zwłaszcza gdy ma on związek z interfejsami Spliterator
i Collector
. Mój problem polega na tym, że po prostu nie rozumiem Spliterator
i Collector
interfejsów jeszcze, w wyniku czego Stream
interfejs jest nadal dla mnie nieco niejasny.
Czym dokładnie jest a Spliterator
i a Collector
i jak ich używać? Jeśli chcę napisać własne Spliterator
lub Collector
(i prawdopodobnie moje Stream
w tym procesie), co powinienem zrobić, a czego nie?
Czytałem kilka przykładów rozsianych po sieci, ale ponieważ wszystko tutaj jest wciąż nowe i podlega zmianom, przykłady i samouczki są nadal bardzo rzadkie.
źródło
Collectors.of
stara metoda wersji beta została usunięta, czy czegoś mi brakuje? Dla kompletności(x,y) -> x+y
można zapisać jakoInteger::sum
.Spliterator
w zasadzie oznacza „podzielny Iterator”.Pojedynczy wątek może przechodzić / przetwarzać cały Spliterator, ale Spliterator ma również metodę,
trySplit()
która „oddziela” sekcję dla kogoś innego (zwykle innego wątku) do przetworzenia - pozostawiając bieżący rozdzielacz z mniejszą ilością pracy.Collector
łączy specyfikacjęreduce
funkcji (mapy-redukuj sławy) z wartością początkową i funkcją łączącą dwa wyniki (umożliwiając w ten sposób łączenie wyników z podzielonych strumieni pracy).Na przykład najbardziej podstawowy Collector miałby początkową wartość 0, dodawałby liczbę całkowitą do istniejącego wyniku i „łączyłby” dwa wyniki, dodając je. W ten sposób sumując podzielony strumień liczb całkowitych.
Widzieć:
Spliterator.trySplit()
Collector<T,A,R>
źródło
Poniżej przedstawiono przykłady użycia predefiniowanych kolektorów do wykonywania typowych zadań redukcji mutowalności:
źródło
Interfejs
Spliterator
- to podstawowa funkcja strumieni .W interfejsie są prezentowane metody
stream()
iparallelStream()
metody domyślneCollection
. Te metody używają Spliteratora poprzez wywołanie metodyspliterator()
:Spliterator to wewnętrzny iterator, który dzieli strumień na mniejsze części. Te mniejsze części mogą być przetwarzane równolegle.
Wśród innych metod są dwie najważniejsze metody zrozumienia Spliteratora:
boolean tryAdvance(Consumer<? super T> action)
W przeciwieństwie doIterator
, próbuje wykonać operację z następnym elementem. Jeśli operacja zostanie wykonana pomyślnie, metoda zwracatrue
. W przeciwnym razie zwracafalse
- to znaczy, że nie ma elementu lub końca strumienia.Spliterator<T> trySplit()
Ta metoda umożliwia podzielenie zestawu danych na wiele mniejszych zestawów według jednego lub drugiego kryterium (rozmiar pliku, liczba wierszy itp.).źródło