Java8에서 도입된 Stream의 distinct()
에 대해서 알아보겠습니다.
1. Stream의 distinct() 메소드
distinct
의 사전적 의미는 '구별할 수 있는'
입니다. Stream에서 distinct()
메소드는 스트림에서 중복되는 요소들을 모두 제거해주고 새로운 스트림을 반환합니다.
아래 예제에서 stream1은 리스트에 대한 스트림이고, stream2는 stream1에서 중복이 제거된 요소들의 스트림이 됩니다. distinct()
가 중복을 제거하고 새로운 스트림을 리턴합니다.
List<String> strings =
Arrays.asList("google", "apple", "google", "apple", "samsung");
Stream<String> stream1 = strings.stream();
Stream<String> stream2 = stream1.distinct();
stream2.forEach(System.out::println);
Output:
google
apple
samsung
참고로, distinct()
메소드에서 중복 요소를 확인할 때, 동일한 객체인지 판단하는 기준은 Object.equals(Object)
메소드입니다.
위의 예제에서 String 클래스는 equals()
가 이미 구현되어 있어서 문제가 없는데 Custom 클래스를 사용한다면 올바르게 구현이 올바른지 확인해 볼 필요는 있습니다.
2. Custom 클래스에 대한 distinct() 사용 예제
distinct()
에서 중복을 판별하는 기준이 equals()
라고 하였습니다. 만약 커스텀 클래스에서 equals()
를 재정의하지 않으면 기본적으로 상속받은 equals()
를 사용합니다.
만약 클래스의 특정 요소만 같으면 동일 객체라고 판단하고 싶을 때는, equals()
를 자신의 상황에 맞게 재정의해야 합니다.
주의할 점은, equals()
를 재정의할 때 hashCode()도 함께 재정의해야 합니다. distinct()
에서 중복 요소를 판별할 때 먼저 hashCode()
를 이용하여 객체가 서로 다른지 확인하고 equals()
로 같은지 체크하는 것 같습니다. 만약 둘 중에 하나라도 재정의되어 있지 않으면 올바르게 동작하지 않을 수 있습니다.
아래 예제는 MyString라는 커스텀 클래스를 정의하고 hashCode()와 equals()
를 재정의하였습니다.
public class StreamExample5 {
public static void main(String args[]) {
List<MyString> myStrings =
Arrays.asList(new MyString("google"),new MyString("apple"),
new MyString("google"), new MyString("apple"), new MyString("samsung"));
Stream<MyString> stream3 = myStrings.stream();
Stream<MyString> stream4 = stream3.distinct();
stream4.forEach(System.out::println);
}
public static class MyString {
public String str;
public MyString(String str) {
this.str = str;
}
@Override
public boolean equals(Object o) {
if (o instanceof MyString) {
return str.equals(((MyString) o).str);
}
return false;
}
@Override
public int hashCode() {
return str.hashCode();
}
@Override
public String toString() {
return str;
}
}
}
Output:
google
apple
samsung
Related Posts
- Java - Unsupported class file major version 61 에러
- Java - String.matches()로 문자열 패턴 확인 및 다양한 예제 소개
- Java - 문자열 공백제거 (trim, replace)
- Java - replace()와 replaceAll()의 차이점
- Java - ArrayList 초기화, 4가지 방법
- Java - 배열 정렬(Sorting) (오름차순, 내림차순)
- Java - 문자열(String)을 비교하는 방법 (==, equals, compare)
- Java - StringBuilder 사용 방법, 예제
- Java - 로그 출력, 파일 저장 방법 (Logger 라이브러리)
- Java IllegalArgumentException 의미, 발생 이유
- Java - NullPointerException 원인, 해결 방법
- Seleninum의 ConnectionFailedException: Unable to establish websocket connection 해결
- Java - compareTo(), 객체 크기 비교
- Java - BufferedWriter로 파일 쓰기
- Java - BufferedReader로 파일 읽기
- Java charAt() 함수 알아보기
- Java - BigInteger 범위, 비교, 연산, 형변환
- Java contains()로 문자(대소문자 X) 포함 확인
- Java - Set(HashSet)를 배열로 변환
- Java - 문자열 첫번째 문자, 마지막 문자 확인
- Java - 문자열 한글자씩 자르기
- Java - 문자열 단어 개수 가져오기
- Java - 1초마다 반복 실행
- Java - 배열을 Set(HashSet)로 변환
- Java - 여러 Set(HashSet) 합치기
- Java - 명령행 인자 입력 받기
- Java - 리스트 역순으로 순회, 3가지 방법
- Java - 특정 조건으로 리스트 필터링, 3가지 방법
- Java - HashMap 모든 요소들의 합계, 평균 계산
- Java - 특정 조건으로 HashMap 필터링
- Java - 싱글톤(Singleton) 패턴 구현
- Java - 숫자 왼쪽에 0으로 채우기
- Java - String 배열 초기화 방법
- Java - 정렬된 순서로 Map(HashMap) 순회
- Java - HashMap에서 key, value 가져오기