[英]Efficient way to Compare Two List's object values without implenmenting equals()?
我在這里有兩個類似的問題:
但我有一個很糟糕的情況,使這個問題有點復雜。 我需要比較的對象來自一個古老的第三方jar,它沒有equals()函數。 我擔心修改它的代碼。
我想出的一個解決方案是構建另外兩個列表,它們的值是原始列表的串聯。 問題2與問題2沒有區別。
但我仍然想知道是否有更好的方法?
嘗試使用Apache Commons isEqualCollection(Collection a,Collection b,Equator equator) ,您仍然需要以與編寫equals override相同的方式實現Equator。
您也可以嘗試這個 ,這是與Apache Commons相同的算法,但有一些性能改進。
第1點:參見Kayaman的評論(提供equals
函數的包裝類)。
第2點:此包裝類可能另外提供lessThan
函數,對元素強加絕對順序。 然后,您可以對兩個列表進行排序,然后逐個元素地進行比較。 這比嘗試在另一個列表中識別一個列表的每個元素更有效,並且還優雅地處理重復的問題。
例如,快速排序的實現示例可以在互聯網上找到,例如這里 。
首先,您需要一個表現良好的對象規范表示。 創建一個名為MyCustomObject
的類(希望你能想到一個更好的名字),它包含原始對象中最相關的屬性,並實現equals(),hashCode()和toString()。 編寫一個構造函數或工廠方法,從原始對象創建MyCustomObject實例。 現在將您的列表轉換為地圖:
List<OriginalObject> list = // wherever you get your list from
Map<MyCustomObject> map = list.stream()
.collect(
Collectors.toMap(
MyCustomObject::new,
(oo)->oo)
);
對兩個列表執行此操作,並比較兩個映射的keySet()。
為了說明Kayaman的答案,你可以這樣做:
public class EqualsWrapper {
private final Object delegate;
public EqualsWrapper(Object toWrap) {
delegate = toWrap;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((delegate == null) ? 0 : delegate.toString().hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EqualsWrapper other = (EqualsWrapper) obj;
return other.toString().equals(obj.toString());
}
}
public static boolean areListsEqual(List list1, List list2){
Set<EqualsWrapper> l_set1 = list1.stream().map(e -> new EqualsWrapper(e)).collect(Collectors.toSet());
Set<EqualsWrapper> l_set2 = list2.stream().map(e -> new EqualsWrapper(e)).collect(Collectors.toSet());
return l_set1.equals(l_set2);
}
但是,如果您擁有非常大的列表並且很有可能它們不相等,那么復制整個列表可能不是最佳選擇。 你也可以遵循這個立場:
public static boolean areListsEqual(List list1, List list2){
return list1.stream().map(e -> new EqualsWrapper(e)).allMatch(e -> list2.stream().map(e -> new EqualsWrapper(e)).anyMatch(e2 -> e2.equals(e)));
}
如果沒有匹配,你會更快地破壞,但有可能失去有關潛在重復的信息。
我的方法還需要實現equals方法,但是每當使用新字段更新對象時,您都不希望更新equals方法。
嘗試一下 ,我相信,這種方法可以接受。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.