Stream reduce() vs. collect() in Java 8


In Java 8, the Stream.reduce() and Stream.collect() methods are used for performing reduction operations, but they are intended for different purposes.

1. Stream.reduce() Method

The reduce() method is primarily used to perform aggregation operations on the elements of a stream, like summing numbers, concatenating strings, etc. It reduces the elements of the stream into a single value.

Syntax:

Optional<T> reduce(BinaryOperator<T> accumulator);
T reduce(T identity, BinaryOperator<T> accumulator);
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);

See the complete example:

ReduceExample.java
package org.websparrow;

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

public class ReduceExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // Using reduce to sum all numbers
        int sum = numbers.stream()
                         .reduce(0, (a, b) -> a + b); // or simply Integer::sum

        System.out.println("Sum: " + sum); // Output: Sum: 15

        // Using reduce without identity value (produces Optional)
        Optional<Integer> product = numbers.stream()
                                           .reduce((a, b) -> a * b);

        product.ifPresent(result -> System.out.println("Product: " + result)); // Output: Product: 120
    }
}

2. Stream.collect() Method

The collect() method is more flexible and is used to transform the elements of the stream into a different form, such as a List, Set, Map, or any other data structure. It is commonly used with collectors like Collectors.toList(), Collectors.toSet(), or Collectors.groupingBy().

Similar Post: IntStream summaryStatistics() in Java 8

Syntax:

<R, A> R collect(Collector<? super T, A, R> collector);

See the complete example:

CollectExample.java
package org.websparrow;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class CollectExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("John", "Jane", "Jack", "Doe");

        // Collect names into a List
        List<String> nameList = names.stream()
                                     .collect(Collectors.toList());

        System.out.println("List: " + nameList); // Output: List: [John, Jane, Jack, Doe]

        // Collect names into a Set (removes duplicates)
        Set<String> nameSet = names.stream()
                                   .collect(Collectors.toSet());

        System.out.println("Set: " + nameSet); // Output: Set: [John, Jane, Jack, Doe]
    }
}

Similar Post: Java 8 Stream API allMatch(), anyMatch() and noneMatch() method Example

3. Key Differences

  • Purpose:
    • reduce() is used for combining all elements of a stream into a single result (e.g., summing numbers, concatenating strings).
    • collect() is used to transform elements of a stream into a different data structure (e.g., List, Set, Map).
  • Output:
    • reduce() produces a single value (which could be an Optional).
    • collect() produces a collection or a complex result.
  • Flexibility:
    • reduce() is mainly for simple reduction operations.
    • collect() is more powerful and can be customized using various Collectors.

4. Summary

In summary, use reduce() for simple aggregation operations and collect() when you need to gather the results into a collection or another complex structure.

References

  1. Stream.reduce() – JavaDoc
  2. Stream.collect()- JavaDoc
  3. Java 8– Find first and all longest strings in List
  4. Java 8 Stream filter() Method Example

Similar Posts

About the Author

Atul Rai
I love sharing my experiments and ideas with everyone by writing articles on the latest technological trends. Read all published posts by Atul Rai.