首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解HashSet

理解HashSet
EN

Stack Overflow用户
提问于 2014-05-09 11:45:59
回答 3查看 485关注 0票数 1

我的问题是,"HashSet对象“可以复制元素吗?

如果我阅读了Set接口定义,我会看到:

不包含重复元素的集合。更正式地说,集合不包含一对元素e1和e2,使得e1.Eques(E2),最多包含一个null元素。顾名思义,这个接口建立了数学集抽象的模型。

现在我们要写一个简单的例子:

定义A类:

代码语言:javascript
复制
public class A {

    @Override
    public boolean equals(Object obj) {
        return true;
    }

}

现在执行这段代码;

代码语言:javascript
复制
Set<A> set = new HashSet<A>();
set.add(new A());
set.add(new A());
System.out.println(set.toString());

这就是结果:

com.maths.graphs.A@b9e9a3,com.maths.graphs.A@18806f7

为什么像HashSet这样实现Set接口的类包含重复的元素?

谢谢!!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-09 11:47:45

你破坏了等价物-hashcode合约。

如果重写equals方法,还必须重写hashCode()方法,以便:

两个相等的对象提供相同的散列,最好是不相等的对象极有可能给出不同的哈希码。

这一点很重要,因为许多对象(包括HashSet)使用哈希代码作为快速、高效的早期步骤,以消除不平等的对象。这就是这里所发生的事情,因为不同A的哈希代码将是不同的,因为它们仍然在使用在object中提供的.hashCode()实现。

如果按照下面的方式创建A类,则集合中不允许超过1A

代码语言:javascript
复制
public class A {

    @Override
    public boolean equals(Object obj) {
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 1; //any number since in this case all objects of class A are equal to everything
        return hash;
    }

}

从javadoc

公共int hashCode() 返回对象的哈希代码值。哈希表(如HashMap提供的哈希表)支持此方法。 hashCode的总合同是:

  • 每当在执行Java应用程序期间在同一个对象上多次调用它时,hashCode方法必须始终如一地返回相同的整数,前提是不修改关于该对象的相等比较中使用的任何信息。从应用程序的一次执行到同一应用程序的另一次执行,这个整数不需要保持一致。
  • 如果两个对象根据等于(对象)方法相等,那么对两个对象调用hashCode方法必须产生相同的整数结果。
  • 如果两个对象根据等于(java.lang.Object)方法是不相等的,则不需要对每个对象调用hashCode方法就必须产生不同的整数结果。但是,程序员应该意识到,为不平等的对象生成不同的整数结果可能会提高哈希表的性能。

大多数IDE将反对,如果您不包括覆盖的HashCode方法时,重叠的相等方法,并可以为您生成一个hashCode方法。

备注

严格地说,我的hashCode()方法并不完全满足合同的要求。由于A#equals( objects )等于,任何,包括不属于A类型的对象,都不可能完全满足合同的要求。理想情况下,等于方法也将改为下面的方法,以涵盖所有的基

代码语言:javascript
复制
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof A){
           return true;
        }else{
           return false;
        }
    }
票数 2
EN

Stack Overflow用户

发布于 2014-05-09 11:48:14

在这里,HashSet没有重复项,因为两个add方法在HashSet中添加了新的对象,它们是不同的对象。由于这个原因,集合的两个元素的哈希代码是不同的。尝试将代码更改为:

代码语言:javascript
复制
Set<A> set = new HashSet<A>();
A a = new A();
set.add(a);
set.add(a);
System.out.println(set.toString());

你会发现集合中只有一个值。

或者只需在代码中添加以下内容并检查

代码语言:javascript
复制
@Override
public int hashCode() {
    return 31;
}
票数 0
EN

Stack Overflow用户

发布于 2015-09-10 08:13:31

您违反了hashCode()方法契约,即对于相同的密钥,它每次都应该返回相同的hashcode()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23563798

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档