2017-05-22 12 views
6

Poniższy kod działa idealnie bez potrzeby inicjowania go.W jaki sposób Stream.reduce (BinaryOperator <T> akumulator)

int sum=Stream.of(2,3).reduce((Integer a,Integer b)->a+b).get(); // sum = 5 
int sum=Stream.of(2,3).reduce((Integer a,Integer b)->a*b).get(); // sum = 6 

Jak to wiedzieć, że pierwszy akumulator jest + więc, że powinien on zainicjować do nowego suma = 0, a drugi akumulator jest * więc, że powinien on zainicjować do nowego suma = 1?

Odpowiedz

7

1-argument reduce nie rozpoczyna się od wartości identyfikacyjnej (0 lub 1). Działa tylko na wartościach w strumieniu. Jeśli spojrzeć na javadoc, to nawet pokazuje równoważny kod:

boolean foundAny = false; 
T result = null; 
for (T element : this stream) { 
    if (!foundAny) { 
     foundAny = true; 
     result = element; 
    } 
    else 
     result = accumulator.apply(result, element); 
} 
return foundAny ? Optional.of(result) : Optional.empty(); 
2

Dopóki Twój strumień ma co najmniej jeden element, nie potrzebujesz wartości tożsamości. Pierwsza redukcja zwraca 2+3, co jest równoważne z 0+2+3. Drugi zwraca 2*3, co odpowiada 1*2*3.

3

To jest jego specyfikacja API:

Optional<T> java.util.stream.Stream.reduce(BinaryOperator<T> accumulator) 

Które zwraca: Opcjonalny opisujące wynik redukcji

As pod numerem javadoc, odpowiednik to:

boolean foundAny = false; 
T result = null; 
for (T element : this stream) { 
    if (!foundAny) { 
     foundAny = true; 
     result = element; 
    } 
    else 
     result = accumulator.apply(result, element); 
} 
return foundAny ? Optional.of(result) : Optional.empty(); 

Trzy przypadki:

  1. Żaden element w strumieniu: powrót Optional.empty()
  2. Jednym z elementów: po prostu wrócić elementu bez stosowania akumulatora w ogóle.
  3. Dwa lub więcej elementów: zastosuj akumulator do wszystkich z nich i zwróć wynik.

Więcej przykładów tej metody zmniejszają:

// Example 1: No element 
Integer[] num = {}; 
Optional<Integer> result = Arrays.stream(num).reduce((Integer a, Integer b) -> a + b); 
System.out.println("Result: " + result.isPresent()); // Result: false 

result = Arrays.stream(num).reduce((Integer a, Integer b) -> a * b); 
System.out.println("Result: " + result.isPresent()); // Result: false 

// Example 2: one element 
int sum = Stream.of(2).reduce((Integer a, Integer b) -> a + b).get(); 
System.out.println("Sum: " + sum); // Sum: 2 

int product = Stream.of(2).reduce((Integer a, Integer b) -> a * b).get(); 
System.out.println("Product: " + product); // Product: 2 

// Example 3: two elements 
sum = Stream.of(2, 3).reduce((Integer a, Integer b) -> a + b).get(); 
System.out.println("Sum: " + sum); // Sum: 5 

product = Stream.of(2, 3).reduce((Integer a, Integer b) -> a * b).get(); 
System.out.println("Product: " + product); // Product: 6 
Powiązane problemy