Stream 클래스에서 제공하는 distinct() 메소드를 활용해 중복을 제거하는 방법에 대해 알아보자.
distinct()
- Stream 클래스 제공하는 메소드로, 중복 요소를 제거하고 고유한 요소로 구성된 새로운 Stream을 반환한다.
- 중복된 요소를 확인하기 위해 equals(), hascode() 메서드를 사용한다.
- 중복된 요소가 존재하는 경우 첫번째 위치의 요소를 반환하기 때문에 정렬 순서를 보장한다.
예제) List
List<Integer> intList = Arrays.asList(1, 3, 2, 3, 5, 5, 7, 6);
List<Integer> intStreamToList = intList.stream()
.distinct() // 중복 제거, 순서 보장o
.collect(Collectors.toList());
System.out.println("intList = " + intList);
System.out.println("intStreamToList = " + intStreamToList);
intList = [1, 3, 2, 3, 5, 5, 7, 6]
intListStream = [1, 3, 2, 5, 7, 6]
distint() 메서드 반환 결과를 Stream이 아닌 List로 반환받기 위해 collect() 메서드를 호출해주었다.
중복이 제거되면서, 순서가 보장된 것을 확인할 수 있다.
예제) 사용자가 정의한 클래스
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
위와 같이 사용자가 정의한 클래스의 경우 distinct() 메소드는 어떻게 중복을 제거할까?
List<Person> personList = Arrays.asList(
new Person("짱구", 7),
new Person("짱구", 7),
new Person("철수", 7),
new Person("철수", 7)
);
List<Person> personListStream = personList.stream()
.distinct()
.collect(Collectors.toList());
personListStream.forEach(System.out::println);
Person{name='짱구', age='7'}
Person{name='짱구', age='7'}
Person{name='철수', age='7'}
Person{name='철수', age='7'}
실행 결과 의도한 대로 중복이 제거되지 않을 것을 확인할 수 있다.
이때 List의 각 요소는 실제 데이터 값이 아닌 참조값을 갖게 된다.
따라서 기본 타입이 아닌 참조 타입인 경우 hashCode()와 equals() 메서드를 재정의해줘야 한다.
class Person {
...
// equals, haschCode 재정의
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
...
}
List<Person> personList = Arrays.asList(
new Person("짱구", 7),
new Person("짱구", 7),
new Person("철수", 7),
new Person("철수", 7)
);
List<Person> personListStream = personList.stream()
.distinct()
.collect(Collectors.toList());
personListStream.forEach(System.out::println);
Person{name='짱구', age='7'}
Person{name='철수', age='7'}
재정의 해준 뒤 중복 제거가 잘 된 것을 확인 할 수 있다.
'☕ Java > API' 카테고리의 다른 글
[Java] 문자열 치환하기 - replace() & replaceAll() & replaceFirst() (0) | 2022.10.28 |
---|---|
[Java] 배열 자르기 - copyOfRange() (2) | 2022.08.31 |