繁体   English   中英

需要澄清有关HashSet和Java中的重复项

[英]Need clarification about HashSet and duplicates in Java

我需要澄清一下java认为重复的内容。

请考虑以下代码:

public class Fruit {

    private String name;
    private int juice;

    public Fruit(String name, int j) {
        this.name=name;
        this.juice=j;
    }

    //some more code here

    public String toString() {
        return this.name;
    }

    public boolean equals(Object fruit) {
        return (((Fruit)fruit).name.equals(this.name));
    }
}

public class Test {

    public static void main(String[] args) {

        Fruit a=new Fruit("Apple", 25);
        Fruit b=new Fruit("Apple", 22);

        HashSet<Fruit> hs=new HashSet<Fruit>();

        hs.add(a);
        hs.add(b);

        System.out.println(a.equals(b));
        System.out.println(hs.size());

    }
}

我创建了一个Fruit类,我重写了equals(),因此如果两个对象的名称相等,则认为它们是等于的。 然后,我将两个Fruit对象(具有相同的名称)添加到HashSet中。

现在,HashSet应该阻止尝试添加两个相等的对象。 虽然,上面代码的输出是:

真2

所以一方面,Java认为这两个对象(a和b)是等于的,另一方面,HashSet并不认为这两个对象是等价的。 那我在这里错过了什么?

提前致谢!

HashSet不认为这两个是平等的。 那我在这里错过了什么?

您错过了在Fruit类中覆盖hashCode

@Override
public int hashCode(){
 return 31 * this.name.hashCode();
}

如果它是equals()则是重复,否则不是。 如果你想确保它做你想要的覆盖equals()方法。

您还必须覆盖hashCode方法,因为HashSet在内部使用HashMap 如果您使用像Eclipse这样的工具,您可以使用它轻松生成两者。

这是hashCode()方法中的问题。 你必须覆盖equals()hashCode()方法。

首先,你实现equals是错误的。 您将参数转换为Fruit而不先检查它是否实际上是Fruit的实例。

其次,当覆盖equals你也必须覆盖hashCode 请参阅http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

HashSet和HashMap使用两件事来检查是否相等。

首先,它使用getHashCode()检查HashCode中的两个对象。

当且仅当HashCode匹配它时,使用equals()方法检查相等性。

如果equals返回true,则认为对象是相同的。

每当在方法中实现equals时,您还必须实现HashCode,并且需要遵循两种方法的行为。 如果你没有像HashMap,HashSet等那样的东西都有未定义和不正确的行为。

您可以在此处查看详细说明: http//www.programcreek.com/2011/07/java-equals-and-hashcode-contract/

Netbeans(以及大多数其他IDE)能够为您自动生成equals和hash代码方法。 只需转到source-> insert code-> equals和hash code

然后,您可以选择要包含的字段,它将为您正确生成两种方法。

Hashset和HashMap在内部调用两个方法来检查相等性。

首先它检查HashCode,因为if对象已经在桶中,它将使用equals方法检查相等性。

在您的情况下,您已重写equals方法但忘记覆盖Hashcode。

@Override
public int hashCode(){
 return "Hash"+ this.name.hashCode();
}

这将为您提供正确的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM