set 集合

2019-10-06  本文已影响0人  大涛先生

Collection接口可以存放重复元素,也可以存放不重复元素。List可以存放重复元素,Set就是不重复的元素。 

通过元素的equals方法,来判断是否为重复元素。 

重写equals判断是否为相同对象

Set集合取出元素的方式可以采用:迭代器,增强 for

Set 怎么保证不重复

因为map中的key是不允许重复的,所以set中的元素不能重复。

HashMap的往里放元素的源码!!!

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;

            //如果key在链表中已存在,则替换为新value  HashMap 可以重复put同一个Key值不同的对象。

            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {

                V oldValue = e.value;

                e.value = value;

                e.recordAccess(this);

                return oldValue;

            }

        }

        modCount++;

        addEntry(hash, key, value, i);

        return null;

    }

分步骤判断添加的Key值:

1、取到新添加Key值得hashCode值。

2、确定数组的index 根据Key的hashCode值和当前table的长度按位取并 h & (length-1);

按位取并,作用上相当于取模mod或者取余%。

这意味着数组下标相同,并不表示hashCode相同

3、这里的hashcode在equals前面,JVM会先判断或运算||的前部分,当这一前部分为true的时候判断终止,返回true(这是为了提高JVM的效率),所以当hashcode不同的时候,equals是不会执行的。

总结为什么Set里面不能有重复?

因为HashMap在put一个Key时会判断,将要放进去的Key的hash值与 目前HashMap中定位到的那个Key的hash值比较。

如果hash值相当,继续比较 这两个对象的地址或者内容是否相当。

如果相当:判断出来要添加的Key与HashMap中的Key重复,把Value的值给替换成最新的。

HashSet中的Value是一个固定值PRESENT。 所以修改不修改无所谓。

重写equals方法后最好重写hashCode方法,否则两个等价对象可能得到不同的hashCode,这在集合框架中使用可能产生严重后果,这样如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,但不重写hashcode,那么我们再new一个新的对象,

当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致,如在存储散列集合时(如Set类),将会存储了两个值一样的对象,

导致混淆,因此,就也需要重写hashcode()

注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:

(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true

(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false

————————————————

上一篇 下一篇

猜你喜欢

热点阅读