比较2套Java

时间:2017-02-12 15:57:03

标签: java list set

我有2个哈希集,都包含x个“名称”(对象)。 我想要查看 Names1 Names2 中的“Names”是什么?

 public static void main (String[] args) {

 Set<Name> Names1 = new HashSet<Name>();
    Names1.add(new Name("Jon"));
    Names1.add(new Name("Mark"));
    Names1.add(new Name("Mike"));
    Names1.add(new Name("Helen"));
    Set<Name> Names2 = new HashSet<Name>();
    Names2.add(new Name("Mark"));
    Names2.add(new Name("Mike"));
    Names2.add(new Name("Sally"));



    Set<Name> listCommon = new HashSet<Name>(); 

    for (Name element : Names1) {
        if (!Names2.contains(element)) {
            listCommon.add(element);
        }
    }

    for (Name element : listCommon) {
        System.out.println(element.getNameString());
    }

}
public class Name {
String ord;

Name(String ord1){
    ord = ord1;
}

public String getNameString(){
    return ord;
}
}

因此,当我运行此代码时,我根本没有输出,导致

'if (!Names2.contains(element)) {' 

从未发生过。但我希望得到的输出是 Jon Helen 。因为它们不在 Names2 中。

2 个答案:

答案 0 :(得分:0)

假设您在equals课程中覆盖hashCodeName方法,则可以使用retainAll Set方法(javadoc here)找出共同的元素。 E.g。

public static void main(String[] args) throws IOException {
    Set<Name> Names1 = new HashSet<Name>();
    Names1.add(new Name("Jon"));
    Names1.add(new Name("Mark"));
    Names1.add(new Name("Mike"));
    Names1.add(new Name("Helen"));
    Set<Name> Names2 = new HashSet<Name>();
    Names2.add(new Name("Mark"));
    Names2.add(new Name("Mike"));
    Names2.add(new Name("Sally"));

    Names1.retainAll(Names2);

    for(Name name : Names1){
        System.out.println(name.getName());
    }
}

此处的示例使用equalshashCode方法的名称类:

class Name{
    private String name;

    public Name(String name){
        this.name = name;
    }

    @Override
    public int hashCode(){
        return null != name ? name.hashCode() : 0;
    }

    @Override
    public boolean equals(Object o){
        return o instanceof Name
                && ((Name)o).name != null
                && this.name != null
                && ((Name)o).name.equals(this.name);
    }

    public String getName() {
        return name;
    }
}

请注意,retainAll方法会修改正在调用的set(在我们的例子中为Names1)。如果要保留原始集,则可以复制另一个集中的元素,并在该实例上调用retainAll

答案 1 :(得分:0)

您的Set::contains检查不起作用,因为您无法覆盖Object::equalsObject::equals的默认实现是检查引用相等性(==),这意味着Name必须是完全相同的实例才能被认为是相同的。

正如其他人所说,你要做的就是在你的Name类中实现hashCode和equals。

如果做不到这一点,您将不得不遍历该集并测试obj1.getNameString().equals(obj2.getNameString())以执行您自己的手动编码且效率低下的Set::contains测试版本。