myślę Reduction operations ustęp z java.util.stream
zbiorczym może odpowiedzieć na to pytanie.Podam najważniejszą część tutaj:
W bardziej ogólnej postaci, operacja zmniejszenia na elementach typu <T>
uzyskując wynik typu <U>
wymaga trzech parametrów:
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
Tutaj element tożsamości jest zarówno początkową wartością początkową dla redukcji, jak i domyślnym wynikiem, jeśli nie ma żadnych elementów wejściowych. Funkcja akumulatora przyjmuje częściowy wynik i następny element i generuje nowy wynik cząstkowy. Funkcja łączenia łączy dwa częściowe wyniki, dając nowy częściowy wynik. (Kombinator jest konieczny przy równoległych redukcjach, gdzie dane wejściowe są podzielone, częściowa kumulacja obliczona dla każdej partycji, a następnie częściowe wyniki są łączone w celu uzyskania końcowego wyniku). funkcja łączenia. Oznacza to, że dla wszystkich u
, combiner.apply(identity, u)
jest równa u
. Dodatkowo funkcja łączenia musi być asocjacyjna i musi być zgodna z funkcją akumulatora: dla wszystkich u
i t
, combiner.apply(u, accumulator.apply(identity, t))
musi być equals()
do accumulator.apply(u, t)
.
Formularz trzyargumentowy jest uogólnieniem dwuargumentowej formy, obejmującym etap mapowania do etapu akumulacji. Mogliśmy ponownie rzucić prostą sumą-of-ciężarami przykład stosując bardziej ogólną postać następująco:
int sumOfWeights = widgets.stream()
.reduce(0,
(sum, b) -> sum + b.getWeight())
Integer::sum);
choć wyraźne zmniejszenie map-forma jest bardziej czytelny, a zatem powinny być zazwyczaj preferowane. Uogólniona forma jest przewidziana dla przypadków, w których można zoptymalizować znaczną pracę przez połączenie mapowania i zredukowania do jednej funkcji.
Innymi słowy, o ile mi zrozumieć, forma trzy argument jest przydatna w dwóch przypadkach:
- Gdy równoległe sprawy egzekucyjne.
- Gdy można osiągnąć znaczącą optymalizację wydajności, łącząc etapy mapowania i akumulacji. W przeciwnym razie można użyć prostszej i czytelnej, jawnej formy zmniejszania liczby map.
zrozumiały sposób wspomniano poprzednio w tym samym dokumencie:
int sumOfWeights = widgets.parallelStream()
.filter(b -> b.getColor() == RED)
.mapToInt(b -> b.getWeight())
.sum();
Ów funkcji rzeczywiście. Ciekawa myśl o paralelności - wypróbuje to ... –
To by się wydawało. Wstawienie ".parallel()" powoduje zwrócenie 1000000. –
@Garth fajne, nie mogę się doczekać, aby wypróbować to sam! –