Language/Java

15-4(2). 스트림의 최종 연산 - Collect

리져니 2021. 8. 5. 20:15

Collect(): 그룹별로 나눠서 리듀싱을 할때 사용

스트림의 요소를 수집하는 최종 연산으로 Collector를 매개변수로 하며, 가장 복잡하면서도 유용하게 횔용될 수 있다.

* 매개변수가 Collector를 구현한 클래스의 객체여야한다.

 

collect()가 스트림의 요소를 수집하려면, 어떻게 수집할 것인가에 대한 방법이 정의되어야 하는데, 이 방법을 구현한 것이 collector이다.

collector는 Collector인터페이스를 구현한 것으로, 직접 구현(잘 안씀)할 수도 있고 미리 작성된 것을 사용할 수도 있다.

 

 

스트림을 컬렉션과 배열로 변환: toList(), toSet(), toMap(), toCollection(), toArray()

스트림의 모든 요소를 컬렉션에 수집하기위해 toList()와 같은 메서드를 사용하면 된다.

List<String> names = stuStream.map(Student::getName).collect(Collectors.toList());

 

List나 Set이 아닌 특정 컬렉션을 저장하려면, toCollection()에 해당 컬렉션의 생성자 참조를 매개변수로 넣어주면 된다.

ArrayList<String> list = names.stream().collect(Collectors.toCollection(ArrayList:new));

 

Map은 key-value로 저장해야하므로 객체의 어떤 필드를 키와 값으로 사용할지를 지정해줘야 한다

Map<String, Person> map = personStream.collect(Collectors.toMap(p -> p.getRegId(), p -> p));

 

스트림에 저장된 요소들을 T[]타입의 배열로 변환하려면 toArray()를 사용하면된다.

단, 해당 타입의 생성자 참조를 매개변수로 지정해줘야 한다.

Student[] stuNames = studentStream.toArray(Student[]::new);

 

통계: counting(), summingInt(), averageInt(), maxBy(), minBy()

최종 연산들이 제공하는 통계 정보를 얻을 수 있다.

long count = stuStream.collect(counting());
long totalScore = stuStream.collect(summiingInt(Student::getTotalScore)); // 그룹별 합계가 가능함

// 비교 기준을 총점으로하여 그룹별로 제일 큰값을 구할수있다
Optional<Student> topStudent = stuStream.collect(maxBy(Comparator.comparingIng(Student::getTotalScore)));

 

리듀싱: reducing()

그룹별 리듀싱이 가능하다

스트림의 요소를 출력하는 용도로 많이 사용된다.

IntStream에서는 매개변수 3개짜리 collect()만 정의되어 있으므로 boxed()를 통해 IntStream을 Stream<Integer>로 변환해야 매개변수 1개짜리 collect()를 쓸수 있다.

 

예제

IntStream intStream = new Randon().ints(1, 46).distinct().limit(6);

OptionalInt max = intStream.reduce(Integer::max);	// 전체 리듀싱
Optional<Integer> max = intStream.boxed().collect(reducing(Integer::max));	// 그룹별 리듀싱

long sum = intStream.reduce(0, (a,b) -> a + b);
long sum - intStream.boxed().collect(reducing(0, (a,b) -> a + b));

 

문자열 결합: joining()

문자열 스트림의 모든 요소를 하나의 문자열로 연결해서 반환한다. 구분자를 지정해줄 수 있고 접두사와 접미사 지정도 가능하다.

스트림의 요소가 String이나 StringBuffer처럼 CharSequence의 자손인 경우에만 결합이 가능하다.

때문에 스트림의 요소가 문자열이 아닌 경우에는 map()으로 스트림의 요소를 문자열로 변환한뒤 사용해야 한다.

 

예제

String studentNames = stuStream.map(Student::getName).collect(joining());
STring studentNames = stuStream.map(Student::getName).collect(joining(",")); // 구분자 ','

// 구분자 ','와 접미사 '[', 접두사 ']'
STring studentNames = stuStream.map(Student::getName).collect(joining(",","[","]"));
728x90

'Language > Java' 카테고리의 다른 글

[JAVA] 정규 표현식  (0) 2021.10.28
16-1. 입출력 I/O: 바이트기반 스트림  (0) 2021.08.08
15-4(1). 스트림의 최종 연산  (0) 2021.08.05
15-3. Optional  (0) 2021.08.05
15-2. 스트림의 중간 연산  (0) 2021.08.05