collect 메서드는 스트림의 요소를 모아서 변환 및 그룹화 하는 작업을 수행하며 두가지 버전이 존재한다.
(1) Supplier , BiConsumer , BiConsumer 를 직접 사용하는 버전
(2) Collector를 이용한 간접적인 버전
@Test
public void 직접_collect구성하기() {
Stream<Integer> stream = Stream.of(1,2,3,4,5);
//stream<Integer> 객체를 List<Integer> 로 변환해보자
List<Integer> result =
stream.collect(
//Supplier : 새로운 List를 생성(공급) 하겠다.
() -> new ArrayList<>(),
//BiConsumer : 각각의 요소를 리스트에 추가하는 작업을 하겠다.
(list , element) -> list.add(element),
//BiConsumer : 각 요소를 병합하겠다 (여기서는 사용하지 않음)
(list1, list2) -> list1.addAll(list2)
);
result.stream().forEach(System.out::println);
출력결과
1
2
3
4
5
}
[코드 설명]
Supplier
새로운 객체를 생성해주는 함수이다.
여기서는 stream객체를 List로 변경하기 위한 공간으로 ArrayList를 생성했다.
BiConsumer (accumulator)
첫번째 인자는 누적된 결과를 나타낼 리스트 , 두번쨰는 스트림에서 가져온 인수를 의미한다.
즉 스트림의 요소를 하나씩 리스트에 추가해주는 역할을 한다.
BiConsumer (combiner)
병렬 스트림일때만 사용하고, 실행 결과 리스트를 병합하는 역할을 하며 여기서는 사용되지 않았다. 음..근데 null로 세팅을 하면 nullException이 나기에 그냥 세팅을 했다.
*참고로 BiConsumer의 의미는 Bi(2개의) 인자를 받고 리턴값이 없는 함수형 인터페이스를 의미한다.
@Test
public void 간접_collect구성하기() {
Stream<Integer> stream = Stream.of(1,2,3,4,5);
List<Integer> result =
stream.collect( Collectors.toList() );
result.stream().forEach(System.out::println);
}
}
collect 메서드를 이용해서 요소들을 모아 List 객체로 변환하였다.
Collectors.toList() 를 살펴보면 아래와 같다.

사실상 toList()를 실행하면서 ArrayList::new (생성) , List::add (요소추가) , (left , right) -> { ... } (병합) 처리를 하는 것을 볼 수 있다.
즉 직접적인 방식이나 간접적인 방식 모두 동일한 실행을 하지만
아무래도 개발자 입장에서는 간접적으로 처리하는게 더 편할 것 같다.