[英]Merging two List of objects in java 8
我有一個Java類Parent
有20個屬性(attrib1, attrib2 .. attrib20)
及其相應的getter和setter。 我還有兩個Parent
對象列表: list1
和list2
。
現在我想合並兩個列表並避免基於attrib1
和attrib2
重復對象。
使用Java 8:
List<Parent> result = Stream.concat(list1.stream(), list2.stream())
.distinct()
.collect(Collectors.toList());
但是我必須在哪個地方指定屬性? 我應該覆蓋hashCode
和equals
方法嗎?
如果你想實現equals
和hashCode
,那么它的位置就在 Parent
類中。 在該類中添加類似的方法
@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());
}
如果你這樣做,在Stream<Parent>
上調用distinct()
將自動做正確的事情。
如果您不希望(或不能)更改類Parent
,則沒有用於相等的委派機制,但您可以使用具有委派機制的排序 :
Comparator<Parent> c=Comparator.comparing(Parent::getAttrib1)
.thenComparing(Parent::getAttrib2)
.thenComparing(Parent::getAttrib3)
// …
.thenComparing(Parent::getAttrib19)
.thenComparing(Parent::getAttrib20);
這定義了基於屬性的訂單。 它要求屬性本身的類型具有可比性。 如果你有這樣的定義,你可以使用它來實現基於該Comparator
的distinct()
的等價物:
List<Parent> result = Stream.concat(list1.stream(), list2.stream())
.filter(new TreeSet<>(c)::add)
.collect(Collectors.toList());
如果您想將其與並行流一起使用,還有一個線程安全的變體:
List<Parent> result = Stream.concat(list1.stream(), list2.stream())
.filter(new ConcurrentSkipListSet<>(c)::add)
.collect(Collectors.toList());
例如:
public class Parent {
public int no;
public String name;
@Override
public int hashCode() {
return (no << 4) ^ name.hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Parent))
return false;
Parent o = (Parent)obj;
return this.no == o.no && this.name.equals(o.name);
}
}
覆蓋Parent
類中的equals
和hashCode
方法,以避免列表中的重復。 這將為您提供您想要的確切結果。
如果要覆蓋.equals(…)
和.hashCode()
,則需要在Parent
類上執行此操作。 請注意,這可能會導致Parent
其他用途失敗。 Alexis C.的鏈接解決方案更加保守。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.