Ответ
Операция distinct() — это промежуточная операция, которая возвращает новый поток, содержащий только уникальные элементы исходного потока, удаляя дубликаты.
Механизм работы:
Для определения уникальности элементов distinct() использует:
- Метод
equals(Object)для сравнения элементов. - Метод
hashCode()для оптимизации (элементы с разным хэш-кодом считаются разными).
Пример:
List<String> names = Arrays.asList("Alice", "Bob", "Alice", "Charlie", "Bob");
List<String> uniqueNames = names.stream()
.distinct() // Удаляет дубликаты "Alice" и "Bob"
.collect(Collectors.toList());
// Результат: ["Alice", "Bob", "Charlie"] (порядок из исходного списка сохранен)
Критические аспекты для понимания:
- Для пользовательских объектов: Необходимо корректно переопределять
equals()иhashCode(). Без этогоdistinct()будет сравнивать ссылки на объекты, а не их содержимое.// Без переопределения equals/hashCode два разных объекта с одинаковыми полями будут считаться разными. - Stateful операция:
distinct()должен отслеживать уже увиденные элементы. В параллельных стримах это требует синхронизации и может снижать производительность. - Порядок элементов: В упорядоченных стримах (например, созданных из
List) порядок уникальных элементов сохраняется (первое вхождение элемента сохраняется, последующие дубликаты отбрасываются). В неупорядоченных стримах порядок не гарантирован. - Бесконечные потоки: Использование
distinct()на бесконечном потоке может привести к бесконечному выполнению, так как операция ждет завершения потока для гарантии уникальности.