Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java-如何在两个列表之间找到匹配的对象?_Java_Algorithm_List_Data Structures - Fatal编程技术网

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

java-如何在两个列表之间找到匹配的对象?,java,algorithm,list,data-structures,Java,Algorithm,List,Data Structures,给定两个列表,每个列表包含相同的对象类型,我希望根据一些属性值在两个列表之间找到匹配的对象 e、 g.如果L1Obj.a==L2Obj.a和L1Obj.b==L2Obj.c和L1Obj.c==L2Obj.c,则列表1中的对象L1Obj与列表2中的对象L2Obj匹配 这些属性不是类的唯一属性,而是唯一标识列表中对象所需的全部属性 我的问题是——实现这一目标的最佳方式是什么 一种方法是基于列表构造HashMaps,使用concateand字符串值a+b+c作为索引对象的键。这样我就可以遍历第一个列表

给定两个列表,每个列表包含相同的对象类型,我希望根据一些属性值在两个列表之间找到匹配的对象

e、 g.如果L1Obj.a==L2Obj.a和L1Obj.b==L2Obj.c和L1Obj.c==L2Obj.c,则列表1中的对象L1Obj与列表2中的对象L2Obj匹配

这些属性不是类的唯一属性,而是唯一标识列表中对象所需的全部属性

我的问题是——实现这一目标的最佳方式是什么

一种方法是基于列表构造HashMaps,使用concateand字符串值a+b+c作为索引对象的键。这样我就可以遍历第一个列表,并尝试使用相同的键查找第二个列表中的对象

这听起来怎么样?有没有更好的方法来实现这一点

非常感谢您的帮助


更新:

好的,实际上我还需要一点。找到匹配项后,我想用L2Obj的属性覆盖L1Obj.x、L1Obj.y、L1Obj.z。HashSet听起来很适合查找匹配项,但如果我是对的,它实际上不允许我访问这些匹配项


对此我能做些什么?

我不知道我是否想简单一点,但我会这样尝试:

重写对象的equals方法以实现比较,以检查它是否是同一对象

然后我将迭代第一个列表,并使用contains方法检查对象是否也包含在第二个列表中


然后我将遍历第二个列表,并检查对象是否也在第一个列表中,而不在结果列表中。

与其使用字符串重复,不如使用
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!");
类MyObj{
财产a;
财产b;
财产c;
公共布尔等于(对象o){
//如果属性是基本属性,如int或其他类型,则使用==
返回MyObj&&a.equals(o.a)&&b.equals(o.b)&&c.equals(o.c)的实例o;
}
//编辑-重写equals时,也重写hashcode
公共int hashCode(){
返回a.hashCode()^b.hashCode()^c.hashCode();
}
公共字符串toString(){
返回a.toString()+“”+b.toString()+“”+c.toString();
}
}
//稍后在您的主要方法中
Set objSet=new HashSet();
对于(MyObj o:list1)objSet.add(o);
for(MyObj o:list2)if(objSet.contains(o))System.out.println(o+“是匹配的!”);

相关对象应实现
布尔等于(对象)
方法。例如:

 L1Obj.equals(L2Obj);

您可以重载该方法,以便实现所需的相等操作。

要查看的对象是否实现了只考虑您关心的字段的
相等(Object)
hashCode()
?如果是这样,您可以从第一个列表创建一个新的
HashSet
,然后调用
retainal()
传入第二个列表


如果它们没有针对您关心的属性实现
equals(Object)
hashCode()
,您可以创建一个
TreeSet
并传入一个查看您关心的属性的
比较器。

您可以做一件事。有两个包含这些对象的列表,并覆盖这些对象所属类的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,反之则不正确。

您可以编辑列表中存储的类的代码吗?您需要将
equals(MyObj o)
更改为
equals(Object o)
。您没有重写所写的等于。@Titan-我注意到在您的注释之前缺少哈希代码:)。我原以为您可以将其保留为MyObj,但我会将其清理以符合标准。使用
retainAll