앞서 collect()와 reduce()를 배웠다.
https://standout.tistory.com/1447
collect()는 reduce()와 유사하다.
스트림의 모든 요소를 결합하여 단일 결과를 생성하는 최종 연산.
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// 1부터 5까지의 정수를 모두 더한 결과 출력
int sum = Stream.of(1, 2, 3, 4, 5)
.reduce(0, Integer::sum);
System.out.println("Sum: " + sum);
}
}
[출력결과]
Sum: 15
collect()
스트림의 최종연산중 가장 복잡하면서도 유용하다.
스트림의 요소를 컬렉션으로 수집하는 최종 연산
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// 문자열 길이가 5 이상인 요소를 리스트로 수집하여 출력
List<String> result = Stream.of("apple", "banana", "cherry", "date")
.filter(s -> s.length() >= 5)
.collect(Collectors.toList());
System.out.println("Result: " + result);
}
}
[출력결과]
Result: [banana, cherry]
collect()는 매개변수 타입이 Collector이다.
Collector객체여야 한다는 말.
두 가지 오버로드된 형태가 있다.
아래의 두 코드는 모두 스트림에서 요소를 수집해 List로 변환하는 작업을 수행하고 출력결과는 같으나,
첫번째는 Collector를 사용하여 수집하고, 두번째는 Supplier, BiConsumer, BiConsumer를 직접제공해 수현한다.
Object collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)형태는 수집과정을 더욱 세밀하게 제어하고싶을때 사용한다.
1. Object collect(Collector collector)
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream<String> stream = Stream.of("Apple", "Banana", "Orange");
// Collector를 사용하여 List로 요소 수집
List<String> collectedList = stream.collect(Collectors.toList());
System.out.println(collectedList); // 출력: [Apple, Banana, Orange]
}
}
2. Object collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)
매개변수가 3개나 정의된 collect()는 잘 사용되지않으나 Collector인터페이스를 구현하지않고 람다식으로 간단히 수집할때 편리하다고 우선 이해하자.
아래 코드를 보면 마지막 combiner는 보통 리스트를 병합되는데 사용되어 ArrayList::addAll형태로 사용되는 경우가 많으나
그저 합치는것이 아닌 각 요소들을 연결하는 문자열을 생성하고자 할때 combiner이 로직을 제공할 수 있다.
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream<String> stream = Stream.of("Apple", "Banana", "Orange");
// supplier: 새로운 ArrayList 생성
// accumulator: 각 요소를 대문자로 변환하여 리스트에 추가
// combiner: 병렬 실행 시 리스트를 병합하지 않음 (사용하지 않음)
List<String> collectedList = stream.collect(
ArrayList::new,
(list, element) -> list.add(element.toUpperCase()), // 각 요소를 대문자로 변환하여 리스트에 추가
ArrayList::addAll
);
System.out.println(collectedList); // 출력: [APPLE, BANANA, ORANGE]
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream<String> stream = Stream.of("Apple", "Banana", "Orange");
// combiner를 사용하여 리스트를 문자열로 병합
String result = stream.parallel().collect(
StringBuilder::new, // supplier: 새로운 StringBuilder 생성
(builder, element) -> builder.append(element).append(", "), // accumulator: 각 요소를 문자열로 이어붙임
(builder1, builder2) -> builder1.append(builder2.toString()) // combiner: 두 개의 StringBuilder를 이어붙임
).toString();
// 마지막에 추가된 ", "을 제거
if (!result.isEmpty()) {
result = result.substring(0, result.length() - 2);
}
System.out.println("Result: " + result); // 출력: Apple, Banana, Orange
}
}