Jeśli chcesz realizować equals
i hashCode
, miejscem na to jest wewnątrz klasa Parent
. W ramach tej klasy dodać metody jak
@Override
public int hashCode() {
return Objects.hash(getAttrib1(), getAttrib2(), getAttrib3(),
// …
getAttrib19(), getAttrib20());
}
@Override
public boolean equals(Object obj) {
if(this==obj) return true;
if(!(obj instanceof Parent)) return false;
Parent p=(Parent) obj;
return Objects.equals(getAttrib1(), p.getAttrib1())
&& Objects.equals(getAttrib2(), p.getAttrib2())
&& Objects.equals(getAttrib3(), p.getAttrib3())
// …
&& Objects.equals(getAttrib19(), p.getAttrib19())
&& Objects.equals(getAttrib20(), p.getAttrib20());
}
Jeśli to zrobił, distinct()
powoływać na Stream<Parent>
automatycznie zrobić dobry uczynek.
Jeśli nie chcą (lub nie mogą) zmienić klasę Parent
, nie ma mechanizmu delegacja dla równości, ale można uciec się do zamawiania jako że posiada mechanizm delegacji:
Comparator<Parent> c=Comparator.comparing(Parent::getAttrib1)
.thenComparing(Parent::getAttrib2)
.thenComparing(Parent::getAttrib3)
// …
.thenComparing(Parent::getAttrib19)
.thenComparing(Parent::getAttrib20);
Definiuje zamówienie na podstawie właściwości. Wymaga, aby typy samych atrybutów były porównywalne. Jeśli masz taką definicję, można go używać do wdrożenia odpowiednik distinct()
, w oparciu o które Comparator
:
List<Parent> result = Stream.concat(list1.stream(), list2.stream())
.filter(new TreeSet<>(c)::add)
.collect(Collectors.toList());
Istnieje również wariant bezpieczny wątku, w przypadku, gdy chcesz go używać z równoległych strumieni :
List<Parent> result = Stream.concat(list1.stream(), list2.stream())
.filter(new ConcurrentSkipListSet<>(c)::add)
.collect(Collectors.toList());
Użyj opcji Ustaw, aby uniknąć powtarzania wartości. – Noundla
Zobacz http://stackoverflow.com/questions/27870136/java-lambda-stream-distinct-on-arbitrary-key/27872086 –
Ciekawa funkcja echa, którą tam masz :) – CKing