Java Stream distinct() Funktion
Die Java Stream distinct()-Methode gibt einen neuen Stream von unterscheidbaren Elementen zurück. Sie ist nützlich, um doppelte Elemente aus der Sammlung zu entfernen, bevor sie verarbeitet werden.
Java Stream distinct() Methode
Die Elemente werden mit der equals()-Methode verglichen. Daher ist es notwendig, dass die Stream-Elemente eine ordnungsgemäße Implementierung der equals()-Methode haben.
Wenn der Stream geordnet ist, wird die Begegnungsreihenfolge beibehalten. Das bedeutet, dass das zuerst auftretende Element im Stream der unterscheidbaren Elemente vorhanden sein wird.
Wenn der Stream ungeordnet ist, dann können die resultierenden Stream-Elemente in beliebiger Reihenfolge sein.
Stream distinct() ist eine zustandsbehaftete Zwischenoperation.
Die Verwendung von distinct() mit einem geordneten parallelen Stream kann aufgrund erheblicher Pufferungsüberlastung eine schlechte Leistung haben. In diesem Fall sollte mit sequentieller Stream-Verarbeitung fortgefahren werden.
Doppelte Elemente mit distinct() Funktion entfernen
Lassen Sie uns sehen, wie die stream distinct()-Methode verwendet wird, um doppelte Elemente aus einer Sammlung zu entfernen.
jshell> List<Integer> list = List.of(1, 2, 3, 4, 3, 2, 1);
list ==> [1, 2, 3, 4, 3, 2, 1]
jshell> List<Integer> distinctInts = list.stream().distinct().collect(Collectors.toList());
distinctInts ==> [1, 2, 3, 4]
Verarbeitung nur einzigartiger Elemente mit Stream distinct() Funktion und forEach()
Da distinct() eine Zwischenoperation ist, können wir die forEach()-Methode damit verwenden, um nur die einzigartigen Elemente zu verarbeiten.
jshell> List<Integer> 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
Stream distinct() mit benutzerdefinierten Objekten
Lassen Sie uns ein einfaches Beispiel anschauen, wie distinct() verwendet wird, um doppelte Elemente aus einer Liste zu entfernen.
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<Data> 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<Data> 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);
}
}
Output:
Data List = [Data[10], Data[20], Data[10], Data[20]]
Unique Data List = [Data[10], Data[20], Data[10], Data[20]]
Die distinct()-Methode hat die doppelten Elemente nicht entfernt. Es liegt daran, dass wir die equals()-Methode in der Data-Klasse nicht implementiert haben. Daher wurde die equals()-Methode der Superklasse Object verwendet, um gleiche Elemente zu identifizieren. Die Implementierung der equals()-Methode der Object-Klasse ist:
public boolean equals(Object obj) {
return (this == obj);
}
Da die Data-Objekte die gleichen IDs hatten, aber auf unterschiedliche Objekte verwiesen, wurden sie als nicht gleich angesehen. Deshalb ist es sehr wichtig, die equals()-Methode zu implementieren, wenn Sie vorhaben, die stream distinct()-Methode mit benutzerdefinierten Objekten zu verwenden. Beachten Sie, dass sowohl die equals() als auch die hashCode()-Methoden von der API der Collection-Klassen verwendet werden, um zu überprüfen, ob zwei Objekte gleich sind oder nicht. Daher ist es besser, eine Implementierung für beide bereitzustellen.
@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;
}
Tipp: Sie können die equals() und hashCode() Methode einfach generieren, indem Sie die Option “Eclipse > Quelle > Generate equals() and hashCode()” verwenden. Der Output nach dem Hinzufügen der equals() und hashCode() Implementierung ist:
Data List = [Data[10], Data[20], Data[10], Data[20]]
Data equals method
Data equals method
Unique Data List = [Data[10], Data[20]]