hashset是通过hashmap来实现的,将元素添加到hashset中就相当于添加到hashmap的键中,而hashmap添加元素的时候本身就会调用hash和equals方法来计算键值得hash值和判断是否重复,为什么添加到hashset中的元素还要添加hashcode和equals方法

解决方案 »

  1.   

    首先我也是菜鸟啊
     hashset集合在将一个元素添加到集合中时(假设为一个自定义类,并重写了hashcode与equals方法),首先查看该元素所在的地址(hashcode计算出的值)中是否已有元素,如果没有,会直接将该元素添加到集合中,如果有元素,则进行equals方法比较,返回true,不添加,返回false,添加到集合
    如果自定义类不重写hashcode与equals方法,将调用object类的hashcode与equals方法,Object类的hashcode使用的是随机值
    那么hashset集合添加相同的元素依旧会成功,不能保证他的唯一性
    还有一个 Treeset保证唯一性的是他的compareto方法的返回值  ,返回0 不添加,其他数则添加
      

  2.   

    HashSet的实现原理:
    往HashSet添加元素的时候,HashSet会先调用元素的hashCode方法得到元素的哈希值,然后通过元素的哈希值经过移位等运算,就可以算出该元素在哈希表中的存储位置。
    情况1:如果算出元素存储的位置目前没有任何元素存储,那么该元素可以直接存储到该位置上。
    情况2:如果算出该元素的存储位置目前已经存在有其他的元素了,那么会调用该元素的equals方法与该位置的元素再比较一次,如果equals返回的是true,那么该元素与这个位置上的元素就视为重复元素,不允许添加,如果equals方法返回的是false,那么该元素允许添加。所以一个对象要被存储入HashSet,必须重写该对象的hashCode方法和equals方法,且必须保证一致性。
      

  3.   

    hashset的add方法调用的是hashmap的put方法,将元素添加到hashmap的key位置,value位置放的是一个new object(),hashmap的put方法就会通过hash方法和equals方法去重啊,附上hashmap put()方法源码
    public V put(K key, V value) {
            if (key == null)
                return putForNullKey(value);
            int hash = hash(key.hashCode());
            int i = indexFor(hash, table.length);
            for (Entry<K,V> e = table[i]; e != null; e = e.next) {
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                    V oldValue = e.value;
                    e.value = value;
                    e.recordAccess(this);
                    return oldValue;
                }
            }