我在这里有两个类似的问题:
但我有一个很糟糕的情况,这个问题有点复杂。我需要比较的对象来自一个古老的第三方jar,它没有equals()函数。我担心修改它的代码。
我提出的一个解决方案是构建另外两个列表,它们的值是原始列表的串联。问题与问题2没有区别。
但我仍然想知道是否有更好的方法?
答案 0 :(得分:3)
尝试使用Apache Commons isEqualCollection(Collection a, Collection b, Equator equator),您仍然需要以与编写equals覆盖相同的方式实现Equator。
您也可以尝试this one,这与Apache Commons的算法相同,但有一些性能改进。
答案 1 :(得分:0)
第1点:参见Kayaman的评论(提供equals
功能的包装类)。
第2点:此包装类可能另外提供lessThan
函数,对元素强加绝对顺序。然后,您可以对两个列表进行排序,然后逐个元素地进行比较。这比尝试识别另一个列表中每个元素的每个元素更有效,并且还可以优雅地处理重复的问题。
e的实施例。 G。快速排序可以在互联网上找到,例如。 G。 here
答案 2 :(得分:0)
首先,您需要一个表现良好的对象规范表示。
创建一个名为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()。
答案 3 :(得分:0)
为了说明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)));
}
如果没有匹配但您可能会在没有匹配的情况下更快地破解,但是可能会丢失有关潜在重复项的信息。
答案 4 :(得分:0)
我的方法还需要实现equals方法,但是每当使用新字段更新对象时,您都不希望更新equals方法。
Try it out,我相信,这种方法可以接受。