Set接口
HashSet
-
底层HashMap
-
实际上是K,V模式,只不过V放的是一个统一的Object
-
可以存放null值,但是只能有一个null值
-
不能有重复元素
-
这里面需要考虑到hashcode与equals方法的重写
如果放入Set集合的元素只重写hashcode而不重写equals,会导致重复元素添加,源码如下
-
此时认为hashcode是相等的,这两个元素到同一个hash槽里面
并且执行遍历链表寻找插入位置的操作。
-
插入操作源码具体流程,首先调用map的put方法,put方法调用hash方法对key的hashcode再进行hash处理,以减少哈希碰撞,然后再调用putVal方法,将key和Object传入
-
putValue方法首先判断tab数组是否为空,如果为空则会调用resize方法去把table初始化,
如果节点数量大于0.75*数组长度,则会进行扩容
初始化完成之后寻找hash槽,并且插入,如果一个槽里面的链表大于9个的时候会进行树化,但是树化前会进行判断,判断总节点个数是否小于64,如过小于64,则再调用resize方法进行2倍(加载因子)扩容。如果树化之后树的元素小于6,则会再次降级为链表
-
为什么HashMap链表会形成死循环
准确的讲应该是 JDK1.7 的 HashMap 链表会有死循环的可能,因为JDK1.7是采用的头插法,在多线程环境下有可能会使链表形成环状,从而导致死循环。JDK1.8做了改进,用的是尾插法,不会产生死循环。