Рубрики
Без рубрики

Функция Java Stream distinct() для удаления дубликатов

Метод Java Stream distinct() возвращает новый поток отдельных элементов. Это полезно для удаления повторяющихся элементов из коллекции перед обработкой

Автор оригинала: Pankaj Kumar.

Метод Java Stream distinct() возвращает новый поток отдельных элементов. Это полезно для удаления повторяющихся элементов из коллекции перед их обработкой.

Метод Java Stream distinct()

  • Элементы сравниваются с помощью метода equals () . Поэтому необходимо, чтобы элементы stream имели надлежащую реализацию метода equals ().
  • Если поток упорядочен, порядок встреч сохраняется. Это означает, что элемент, встречающийся первым, будет присутствовать в потоке отдельных элементов.
  • Если поток неупорядочен, то результирующие элементы потока могут быть в любом порядке.
  • Функция Stream distinct () – это промежуточная операция с отслеживанием состояния.
  • Использование функции distinct() с упорядоченным параллельным потоком может привести к снижению производительности из-за значительных накладных расходов на буферизацию. В этом случае перейдите к последовательной потоковой обработке.

Удалите дубликаты элементов с помощью функции distinct()

Давайте посмотрим, как использовать метод stream distinct() для удаления повторяющихся элементов из коллекции.

jshell> List list = List.of(1, 2, 3, 4, 3, 2, 1);
list ==> [1, 2, 3, 4, 3, 2, 1]

jshell> List distinctInts = list.stream().distinct().collect(Collectors.toList());
distinctInts ==> [1, 2, 3, 4]

Обработка только уникальных элементов с использованием Stream distinct() и forEach()

Поскольку distinct() является промежуточной операцией, мы можем использовать метод forEach() с ним для обработки только уникальных элементов.

jshell> List list = List.of(1, 2, 3, 4, 3, 2, 1);
list ==> [1, 2, 3, 4, 3, 2, 1]

jshell> list.stream().distinct().forEach(x -> System.out.println("Processing " + x));
Processing 1
Processing 2
Processing 3
Processing 4

Пример Java Stream distinct() forEach()

Поток distinct() с пользовательскими объектами

Давайте рассмотрим простой пример использования функции distinct() для удаления повторяющихся элементов из списка .

package com.journaldev.java;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class JavaStreamDistinct {

	public static void main(String[] args) {
		List dataList = new ArrayList<>();
		dataList.add(new Data(10));
		dataList.add(new Data(20));
		dataList.add(new Data(10));
		dataList.add(new Data(20));

		System.out.println("Data List = "+dataList);

		List uniqueDataList = dataList.stream().distinct().collect(Collectors.toList());

		System.out.println("Unique Data List = "+uniqueDataList);
	}

}

class Data {
	private int id;

	Data(int i) {
		this.setId(i);
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@Override
	public String toString() {
		return String.format("Data[%d]", this.id);
	}
}

Выход:

Data List = [Data[10], Data[20], Data[10], Data[20]]
Unique Data List = [Data[10], Data[20], Data[10], Data[20]]

Метод distinct() не удалял повторяющиеся элементы. Это потому, что мы не реализовали метод equals() в классе данных. Таким образом, метод объекта суперкласса equals() использовался для идентификации равных элементов. Реализация метода класса объектов equals() является:

public boolean equals(Object obj) {
    return (this == obj);
}

Поскольку объекты данных имели одинаковые идентификаторы, но они ссылались на разные объекты, они считались неравными. Вот почему очень важно реализовать метод equals (), если вы планируете использовать метод stream distinct() с пользовательскими объектами.

Обратите внимание, что методы equals() и hashCode() используются API классов коллекций для проверки того, равны ли два объекта или нет. Поэтому лучше предоставить реализацию для них обоих.

@Override
public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + id;
	return result;
}

@Override
public boolean equals(Object obj) {
	System.out.println("Data equals method");
	if (this == obj)
		return true;
	if (obj == null)
		return false;
	if (getClass() != obj.getClass())
		return false;
	Data other = (Data) obj;
	if (id != other.id)
		return false;
	return true;
}

Совет : Вы можете легко сгенерировать метод equals() и hashCode (), используя опцию меню “Eclipse > Источник > Сгенерировать equals() и hashCode ()”.

Вывод после добавления реализации equals() и hashCode() является:

Data List = [Data[10], Data[20], Data[10], Data[20]]
Data equals method
Data equals method
Unique Data List = [Data[10], Data[20

Ссылка : Документ API Stream distinct()