关于HashSet的源码分析
HashSet的分析
我们可以知道在Collection接口中List和Set都是其子接口,而List和Set最大的区别在于一个有序一个无序,一个里面的值可以重复,一个不可以重复,为什么会出现这种原因呢,我们可以剖析一下HashSet的源码。
我们看到下面的源码
我们可以看到在add方法中调用一个HashMap的put方法,key为你用在Set集合里面存放的值,value是一个Object,下来我们来跟踪HashMap的源码,如下图
上面两张图可以看到在HashMap的构造中new了一个数组其大小为16,并且在HashMap中包含一个内部类Entry并实现了 Map.Entry接口,从这里我们可以得出HashMap的底层结构为数组加链表结构。
下来我们看看它的put方法。
从上面我们可以看出先对key值进行判空,如果是空值,将null放入数组的第一个位置,这也就是hashmap为什么可以存在空的键,在putForNullKey方法中,当数组的第一个索引位有链表时,并且其key也为null,那么返回其对应的value,将新的value与key组成新的键值对,这个也说明key为null的在hashmap中只有一个且位置一直在数组的第一位上。
下来果key不为空计算出其key的hashcode,下来通过hash值找到其对应数组的下标位,这里就是为什么HashSet无序的原因,因为其是不可控制的。接下来判断数组中是否存在一样的key,如果存在在原来数组的链表位置替换旧的value,返回值位原来老的value值,不存在通过hash计算出的索引下标把键值插入。
正如上面我所说的,通过key的hashcode值来控制数组的索引位置是体现它的无序性,而通过其传入key的hashcode来与对应位置Entry数组中的hashcode来比较,再通过对象的地址值以及对象内部内容是否相等来比较,保证其的不重复性。
最后第一次写博文,有什么不对或者不妥的地方欢迎留言指教。