본문 바로가기
Java

[Java 8] Stream의 collect()

by asdft 2024. 2. 22.

 

 

collect() 

collector는 Collector 인터페이스를 구현한 것이고, 직접 구현할 수도 있지만, 미리 작성된 것을 사용하기도 한다. Collectors 클래스는 미리 작성된 다양한 collector를 반환하는 static 메서드를 가지고 있다.

구현된 collector를 collect() 메서드의 인자로 넣어 사용한다. 

collect()
스트림의 최종연산, 매개변수로 컬렉터를 필요로 한다.


Collector
인터페이스로 컬렉터는 이를 구현해야 한다.


Collectors
클래스로 static 메서드로 미리 구현한 컬렉터를 제공한다.

 

 Collectors를 통해 어떤 형태로 변경할 수 있는지에 대해서 알아보자.

List<String> givenList = Arrays.asList("a", "bb", "cc", "bb");

 

위와 같은 List가 있다고 가정하자

 

toCollections

> toList, toSet

toList / toSet collector는 모든 Stream elements를 List나 Set instance로 변경하는 메서드이다. 중요한 것은 특정한 Collection으로 변환이 되는것은 아니라는 것입니다. LinkedList로 할 수 있고 그런게 아니라는 거지요. 좀 더 정밀한 컨트롤을 하고싶다면 toCollection을 사용하면 됩니다.

List<String> result = givenList.stream().collect(Collectors.toList()); // a, bb, ccc, dd
Set<String> result = givenList.stream().collect(Collectors.toSet()); // a, bb, ccc

 

 

> toCollection

toCollection 메서드를 이용하여 면 특정한 Collection으로 implementation이 가능합니다.

아래는 Stream 요소들을 LinkedList로 변환하는 방법입니다.

givenList.stream().collect(Collectors.toCollection(람다식));

ex)

givenList.stream().collect(Collectors.toCollection(LinkedList::new));

givenList.stream().collect(Collectors.toCollection(( ) -> new LinkedList<>( ));

 

 

> toMap

toMap collector는 Stream elements들을 Map instance로 변경하는 메서드입니다. keyMapper, valueMapper를 이용하여 처리할 수 있습니다. toMap(keyMapper, valueMapper)의 형태를 띄게 됩니다. 예를 한번 들어보겠습니다.

Map<String, Integer> result = givenList.stream().collect(toMap("key", String::length);

 

이렇게 예제를 구성해 보겠습니다. key라는 이름의 key에 4가지의 elements가 들어가기 때문에 key 충돌이 발생할 것입니다. 이떄 위의 경우는 IllegalStateException가 발생합니다. key 중복이라는 의미입니다. key 중복시 처리방법은 아래와 같이 설정해야합니다.

 

Map<String, Integer> result = givenList.stream()
  .collect(toMap("key", String::length, (old, new) -> old));

 

item은 기존에 들어있던 value이며 identicalItem은 key 중복으로 들어온 value입니다. 이때에는 기존의 값을 사용하겠다고 명시하였습니다.

 

 

> collectingAndThen

CollectingAndThen 메서드는 Collecting을 진행한 후 그 결과로 메서드를 하나 더 호출 할 수 있게 해줍니다.

System.out.println(givenList.stream().collect(collectingAndThen(toList(), 람다식)));

 

ex) System.out.println(givenList.stream().collect(collectingAndThen(toList(), Collection::toString)));

 

위의 예제는 stream을 toList로 만들고 elements를 출력할 수 있는 형태로 만든 것을 println으로 찍어보는 예제입니다. 이때의 givenList.stream().collect(collectingAndThen(toList(), Collection::toString))의 return 값은 collectionAndThen의 뒤의 function의 return값에 따라값니다.

 

 

> joining

joining은 Stream을 List가 아닌 String으로 붙여주거나 할 때 사용하는 메서드입니다.

String result = givenList.stream().collect(joining()); // abbcccdd

joining에 파라미터로 연결 부분에 들어갈 문구를 정할 수 있습니다. 만약 joining(",") 이라고 하면 a,bb,ccc,bb 이렇게 출력됩니다.

 

String result = givenList.stream()
  .collect(joining(" ", "PRE-", "-POST"));

이렇게 사용하면 PRE-a bb ccc dd-POST 이런식으로 출력을 기대할 수도 있습니다.

 

 

> counting

elements의 수를 세는 것입니다.

Long result = givenList.stream().collect(counting());

 

 

> groupingBy

database를 조작할 때나 사용하던 group by를 Collection으로 사용할 수 있습니다.

Map<Integer, List<String>> result = givenList.stream()
  .collect(groupingBy(String::length, toList()));

  // 1, a
  // 2, bb bb
  // 3, ccc

 

이를 응용해서 제작한 filtering되는것은 true, 되지 않는것은 false로 묶어주는 partitioningBy 등이 있습니다.

 

 

>배열로 반환

Collect( )는 아니지만, toArray를 사용한다. 특정한 형을 원할 때는, 인자에 람다식을 넣어주어야 한다.

 

// 배열로 변환
Stream<String> stream4 = Stream.of("1", "2", "3", "4", "5");
Object[] objects = stream4.toArray();

Stream<String> stream5 = Stream.of("1", "2", "3", "4", "5");
String[] stringArray = stream5.toArray((i) -> new String[i]);

 

 

 

[참고]

https://sabarada.tistory.com/41

 

[Java 8] Java 8, Stream의 Collectors

안녕하세요. 이전 시간에 우리가 Stream에 대해서 알아봤던 것 기억하시나요? 오늘은 이어서 Collectors에 대해서 이야기 해보려고 합니다. Collectors란 "Stream을 일반적인 List, Set등으로 변경시키는 Stre

sabarada.tistory.com

https://abcdefgh123123.tistory.com/424 [꾸준함의 기록:티스토리]

'Java' 카테고리의 다른 글

스트림(Stream) - reduce( )  (1) 2024.02.27
박싱(Boxing) & 언박싱(UnBoxing)  (0) 2024.02.22
PriorityQueue란?  (0) 2024.02.21
HashSet 사용법(개념,특징,사용법)  (0) 2024.02.20
[Java] ArrayList와 LinkedList의 차이  (0) 2024.02.18