How to implement custom collector using java 8 stream

--

In Java 8, you can implement a custom collector using the Collector interface. The Collector interface provides a way to accumulate elements of a stream into a mutable result container. To create a custom collector, you need to implement the four main methods defined by the Collector interface: supplier, accumulator, combiner, and finisher.

Here’s a step-by-step guide to implementing a custom collector:

Example: Custom Collector for Accumulating Squares of Integers

Let’s create a custom collector to accumulate the squares of integers into a List<Integer>:

package com.neesri.sample;

import static java.util.List.*;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

public class SquareCollector implements Collector<Integer, List<Integer>, List<Integer>> {

// Step 1: Supplier - Provides an initial mutable container for the accumulation.
@Override
public Supplier<List<Integer>> supplier() {
return ArrayList::new;
}

// Step 2: Accumulator - Accumulates the elements into the mutable container.
@Override
public BiConsumer<List<Integer>, Integer> accumulator() {
return List::add;
}

// Step 3: Combiner - Combines two partial results into one.
@Override
public BinaryOperator<List<Integer>> combiner() {
return (list1, list2) -> {
list1.addAll(list2);
return list1;
};
}

// Step 4: Finisher - Performs the final transformation on the result container.
@Override
public Function<List<Integer>, List<Integer>> finisher() {
return Function.identity();
}

// Additional characteristics - Specifies additional characteristics of the collector.
@Override
public Set<Characteristics> characteristics() {
return Collections.emptySet();
}

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

List<Integer> squares = numbers.stream().collect(new SquareCollector());

System.out.println("Original Numbers: " + numbers);
System.out.println("Squares: " + squares);
}
}

In this example:

  • supplier: Provides an initial ArrayList as the mutable container.
  • accumulator: Appends each squared element to the list.
  • combiner: Combines two lists into one.
  • finisher: Returns the final result (identity function in this case).
  • characteristics: Specifies no additional characteristics.

The SquareCollector can then be used with the collect method in a stream.

Custom collectors provide a powerful way to perform complex aggregations and transformations with Java 8 streams while maintaining readability and composability.

--

--

No responses yet