distinct의 사용 예제
다음은 distinct 메서드의 기본 사용 예제입니다.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class DistinctExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List<Integer> distinctNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(distinctNumbers); // 출력: [1, 2, 3, 4, 5]
}
}
위의 예제에서 distinct 메서드는 리스트에서 중복된 숫자들을 제거하고, 고유한 숫자들로 이루어진 새로운 리스트를 반환합니다.
distinct의 내부 동작
distinct 메서드는 각 요소의 equals 메서드를 사용하여 중복을 판단합니다. 따라서 요소들이 equals와 hashCode 메서드를 올바르게 구현하고 있어야 합니다. 특히 사용자 정의 객체를 사용할 때는 equals와 hashCode 메서드를 잘 구현해야 합니다.
예제
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@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);
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class DistinctExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("John", 25),
new Person("John", 25),
new Person("Jane", 30)
);
List<Person> distinctPeople = people.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(distinctPeople); // 출력: [Person{name='John', age=25}, Person{name='Jane', age=30}]
}
}
위의 예제에서 Person 클래스는 equals와 hashCode 메서드를 올바르게 구현하고 있습니다. 따라서 distinct 메서드는 중복된 Person 객체를 제거하고 고유한 객체들만 남깁니다.
distinct 와 성능
distinct 메서드는 내부적으로 요소들을 Set에 추가하여 중복을 제거합니다. 이 과정은 시간 복잡도가 O(n)으로, 요소의 개수에 비례하여 성능이 저하될 수 있습니다. 특히 스트림의 크기가 클 경우, distinct 연산이 성능에 영향을 미칠 수 있습니다.
병렬 스트림에서의 distinct
distinct 메서드는 병렬 스트림에서도 동일하게 동작하지만, 병렬 처리의 이점은 제한적일 수 있습니다. 병렬 스트림은 기본적으로 ForkJoinPool을 사용하여 작업을 분할 처리하지만, distinct 메서드는 모든 요소를 비교해야 하므로 병렬 처리의 이점을 충분히 누리기 어려울 수 있습니다.
병렬 스트림 예제:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class DistinctExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List<Integer> distinctNumbers = numbers.parallelStream()
.distinct()
.collect(Collectors.toList());
System.out.println(distinctNumbers); // 출력: [1, 2, 3, 4, 5]
}
}
위의 예제는 병렬 스트림에서 distinct를 사용하는 경우로, 결과는 순차 스트림과 동일합니다. 그러나 병렬 처리가 distinct 연산의 성능을 크게 향상시키지는 않습니다.
결론
distinct 메서드는 Java Streams API에서 중복 요소를 제거하는 데 사용되는 중간 연산입니다. 요소의 equals 메서드를 사용하여 중복을 판단하며, Set을 내부적으로 사용하여 고유한 요소들만 남깁니다. 사용자 정의 객체를 사용할 때는 equals와 hashCode 메서드를 올바르게 구현해야 합니다. distinct는 병렬 스트림에서도 사용할 수 있지만, 병렬 처리의 성능 이점은 제한적일 수 있습니다.
'프로그래밍 > JAVA' 카테고리의 다른 글
Java stream 의 Optional.orElseThrow (0) | 2024.07.28 |
---|---|
Multi Datasource 를 이용한 database routing 전략 (0) | 2024.07.06 |
Java Streams API - 2 (0) | 2024.05.26 |
Java Streams API - 1 (0) | 2024.05.26 |