Collector를 구현하려면 Collector 인터페이스를 구현해야한다.
public interface Collector<T, A, R>
- `T`: 수집될 요소의 타입
- `A`: 중간 결과를 누적할 객체의 타입
- `R`: 최종 결과의 타입
public interface Collector<T, A, R> {
Supplier<A> supplier(); //누적할 객체를 생성하는 함수를 반환
BiConsumer<A, T> accumulator(); //스트림의 각 요소를 누적하는 함수를 반환
BinaryOperator<A> combiner(); //병렬 실행 시 두 개의 누적 객체를 병합하는 함수를 반환
Function<A, R> finisher(); //중간 결과를 최종 결과로 변환하는 함수를 반환
Set<Characteristics> characteristics(); //Collector의 특성을 나타내는 집합을 반환
}
스트림에서 문자열의 길이를 합산하는 Collector를 구현하는 예시를 구현해보자.
import java.util.HashSet;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
//`StringLengthCollector` 클래스가 `Collector<String, Integer, Integer>` 인터페이스를 구현
public class StringLengthCollector implements Collector<String, Integer, Integer> {
@Override
public Supplier<Integer> supplier() {
return () -> 0; // 초기값으로 0을 반환하는 Supplier
}
@Override
public BiConsumer<Integer, String> accumulator() {
return (length, str) -> length += str.length(); // 문자열의 길이를 합산하는 BiConsumer
}
@Override
public BinaryOperator<Integer> combiner() {
return Integer::sum; // 정수를 더하는 BinaryOperator
}
@Override
public Function<Integer, Integer> finisher() {
return Function.identity(); // 중간 결과를 최종 결과로 반환하는 함수
}
@Override
public Set<Characteristics> characteristics() {
return new HashSet<>(); // Collector의 특성을 나타내는 집합
}
}
`StringLengthCollector`를 사용하여 결과를 수집해보자.
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream<String> stream = Stream.of("Apple", "Banana", "Orange");
Integer totalLength = stream.collect(new StringLengthCollector());
System.out.println("Total length: " + totalLength); // 출력: Total length: 15
}
}