给定两个列表,每个列表包含相同的对象类型,我希望根据一些属性值在两个列表中找到匹配的对象。
e.g。 List1中的一个对象,L1Obj,匹配来自List2,L2Obj的对象,如果L1Obj.a == L2Obj.a AND L1Obj.b == L2Obj.c AND L1Obj.c == L2Obj.c
这些属性不是该类的唯一属性,而是唯一标识列表中对象所需的属性。
我的问题是 - 实现这一目标的最佳方法是什么?
一种方法是根据列表构造HashMaps,使用a + b + c的concataned String值作为索引对象的键。这样我就可以遍历第一个列表,并尝试使用相同的密钥在第二个列表中查找对象。
这听起来怎么样?有没有更好的方法来实现这个目标?
非常感谢所有帮助!
更新:
好的,实际上我还需要更多。找到匹配后,我想用L2Obj的属性覆盖属性L1Obj.x,L1Obj.y,L1Obj.z。 HashSet听起来很适合找到匹配项,但如果我是对的,它实际上并不允许我访问这些匹配项。
我该怎么办?
答案 0 :(得分:8)
您想要查看实施equals(Object)
和hashCode()
的对象是否只考虑了您关注的字段?如果是这样,您可以从第一个列表中创建一个新的HashSet
,然后通过第二个列表调用retainAll()
。
如果他们没有针对您关注的属性实施equals(Object)
和hashCode()
,则可以创建TreeSet
并传入Comparator
你关心的属性。
答案 1 :(得分:3)
不要使用String repesntation,而是使用HashSet的equals()
方法:
class MyObj {
Property a;
Property b;
Property c;
public boolean equals(Object o) {
// use == if Property is primitive, like int or something
return o instanceof MyObj && a.equals(o.a) && b.equals(o.b) && c.equals(o.c);
}
// edit - when you override equals, also override hashcode
public int hashCode() {
return a.hashCode() ^ b.hashCode() ^ c.hashCode();
}
public String toString() {
return a.toString() + " " + b.toString() + " " + c.toString();
}
}
// later in your main method
Set<MyObj> objSet = new HashSet<MyObj>();
for(MyObj o : list1) objSet.add(o);
for(MyObj o : list2) if(objSet.contains(o)) System.out.println(o + " is a match!");
答案 2 :(得分:1)
你可以做一件事。有两个包含这些对象的列表,并覆盖这些对象所属的类的equals方法。 你的equals方法看起来应该是
@Override
public boolean equals(Object obj)
{
return (this.a == obj.a && this.b == obj.b && this.c == obj.c)
}
另外请记住,一旦覆盖equals方法,您还需要覆盖int hashCode()方法。
需要注意的一点是,实现hashCode()时,2个相等的对象将具有相同的hashCode,而反之则不是真的。
答案 3 :(得分:0)
我不知道我是否想要轻松,但我会这样尝试:
重写对象的equals方法以实现比较以检查它是否是同一个对象
然后我将迭代第一个列表并使用contains方法检查对象是否也包含在第二个列表中。
然后我将迭代第二个列表,检查对象是否也在第一个列表中,而不是已经在结果列表中。
答案 4 :(得分:0)
有问题的对象应该实现boolean equals(Object)
方法。 E.g:
L1Obj.equals(L2Obj);
您可以重载该方法,以便可以实现所需的相等操作。