Java - 如何在两个列表之间找到匹配的对象?

8
给定两个列表,每个列表都持有相同类型的对象,我想根据一些属性值在两个列表之间找到匹配的对象。例如,来自List1的对象L1Obj与来自List2的对象L2Obj匹配,如果L1Obj.a == L2Obj.a AND L1Obj.b == L2Obj.c AND L1Obj.c == L2Obj.c。这些属性不是类的唯一属性,但是这些属性足以在列表中唯一标识一个对象。我的问题是 - 实现这个功能的最佳方法是什么?一种方法是基于列表构建HashMaps,使用a+b+c的连接字符串值作为索引对象的键。这样,我可以遍历第一个列表,并尝试查找第二个列表中具有相同键的对象。这个方案怎么样?是否有更好的方法实现这个功能?非常感谢您的帮助!
更新:好的,实际上我需要更多的东西。在找到匹配项后,我想用L2Obj的属性覆盖L1Obj.x、L1Obj.y和L1Obj.z。HashSet听起来很适合找到匹配项,但如果我没错的话,它实际上不能让我访问这些匹配项。我该怎么做?

你能编辑存储在列表中的类的代码吗? - Alb
5个回答

8

你想查看的对象是否实现了只考虑你关心的字段的 equals(Object)hashCode() 方法?如果是这样,你可以从第一个列表创建一个新的 HashSet,然后调用 retainAll() 并传入第二个列表。

如果它们没有针对你关心的属性实现 equals(Object)hashCode(),你可以创建一个 TreeSet 并传入一个检查你关心的属性的 Comparator


retainAll的使用恰当且得体。 - Steve Kuo

3

不要使用字符串表示法,而是在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!");

你需要将equals(MyObj o)改为equals(Object o)。按照现有的写法,你没有覆盖重写equals方法。 - ILMTitan
@Titan - 我注意到在你的评论之前缺少了hashCode :). 我原本以为你可以将其保留为MyObj,但我会将其清理以符合标准。 - corsiKa

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()时,两个相等的对象将具有相同的hashCode,而反之则不一定成立。


0

相关对象应该实现boolean equals(Object)方法。例如:

 L1Obj.equals(L2Obj);

你可以重载那个方法,这样你就可以实现你想要的相等操作。

0
我不知道自己是否想得太简单了,但我会试着这样做:
覆盖对象的equals方法以实现你的比较,检查它是否为同一对象。
然后,我将遍历第一个列表并使用contains方法检查该对象是否也包含在第二个列表中。
接下来,我将遍历第二个列表并检查该对象是否也在第一个列表中且尚未在结果列表中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接