Java/스트림(Stream)

[Java]스트림(Stream) 중복 값 찾기

DevStory 2022. 4. 5.

Java 8에 도입된 Stream은 일반적으로 요소에 대한 필터링, 매핑 또는 순회하기 위해 사용됩니다. 그리고 중복 요소를 찾는 경우에도 사용할 수 있습니다.

 

이번 포스팅은 Stream에서 중복 값 찾는 방법들을 소개합니다.


Collectors.toSet() 메서드

중복 요소를 찾는 가장 쉬운 방법은 stream의 요소를 Set에 추가하는 것입니다. Set은 중복 값을 포함할 수 없으며 Set.add() 메서드는 불리언(Boolean) 값을 반환합니다. 요소가 추가되면 true가 반환되며 그렇지 않으면 false를 반환합니다.

 

다음은 중복 값을 가지는 Stream 객체입니다.

Stream<String> stream = Stream.of("A", "B", "B", "C", "D", "D");

 

이제 필터링된 요소를 가지는 Set 객체를 생성합니다. Stream의 filter() 메서드를 사용하여 중복 값을 필터링합니다.

Stream<String> stream = Stream.of("A", "B", "B", "C", "D", "D");

Set<String> set = new HashSet<>();

stream.filter(n -> !set.add(n))
      .collect(Collectors.toSet())
      .forEach(item -> System.out.println(item));
        
System.out.println("Set 객체");
System.out.println(set);

[실행 결과]

B
D
Set 객체
[A, B, C, D]

Collectors.toMap() 메서드

또 다른 방법으로 각 요소의 중복 횟수를 구할 수 있습니다. stream의 요소를 Map 컬렉션으로 변환하고 발생 횟수를 계산합니다.

Stream<String> stream = Stream.of("A", "B", "B", "C", "D", "D");

Map<String, Integer> map = stream.collect(
        Collectors.toMap(Function.identity(), value -> 1, Integer::sum)
);

System.out.println(map);

[실행 결과]

{A=1, B=2, C=1, D=2}
반응형

Collectors.groupingBy() 메서드

Collectors.groupingBy() 메서드는 요소를 그룹화하고 Map 객체를 반환합니다. groupingBy() 메서드는 인자로 들어온 값을 그대로 반환하는 Function.identity() 메서드와 요소의 개수를 계산하는 Collectors.counting() 메서드를 매개변수로 받습니다.

 

Collectors.groupingBy() 메서드 실행 후 요소의 개수가 1보다 큰 요소들을 출력합니다.

List<String> li = Arrays.asList("A", "B", "B", "C", "D", "D");

li.stream()
  .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
  .entrySet()
  .stream()
  .filter(element -> element.getValue() > 1)
  .collect(Collectors.toList())
  .forEach(System.out::println);

[실행 결과]

B=2
D=2

Collections.frequency() 메서드

Collections.frequency() 메서드는 각 요소를 순회하여 요소의 개수를 반환합니다. filter() 메서드에서 요소의 개수가 1보다 큰 요소들을 필터링 후 출력합니다.

List<String> li = Arrays.asList("A", "B", "B", "C", "D", "D");

li.stream()
  .filter(i -> Collections.frequency(li, i) > 1)
  .collect(Collectors.toSet())
  .forEach(System.out::println);

[실행 결과]

B
D

​Stream.distinct() 메서드

distinct() 메서드는 중복되는 요소들을 제거하고 새로운 스트림을 반환합니다. distinct() 메서드는 중복되는 요소를 제거하기 위해 equals() 메서드를 사용합니다.

List<String> li = Arrays.asList("A", "B", "B", "C", "D", "D");

List<String> distinctLi = li.stream()
                            .distinct()
                            .collect(Collectors.toList());

System.out.println(distinctLi);

[실행 결과]

[A, B, C, D]

중복되는 값을 찾고 싶은 경우 remove() 메서드를 사용하여 고유한 값을 제거합니다.

List<String> li = new ArrayList(
        Arrays.asList("A", "B", "B", "C", "D", "D")
);

List<String> distinctLi = li.stream()
                            .distinct()
                            .collect(Collectors.toList());

for (String distinctElement : distinctLi) {
  li.remove(distinctElement);
}

System.out.println(li);

[실행 결과]

[B, D]
반응형

댓글