HashSet不可以存储相同元素的原理
哈希表的存储
哈希表是以数组加链表加红黑树来存储数据的。
当相同哈希值的元素大于等于8个时(即哈希冲突的元素超过8个),就会使用红黑树来储存,因为红黑树查询效率很高。
哈希表的存储是首先通过哈希函数来计算哈希值(hashcode())来确定你要放到哈希表里面的哪一个位置。
这里有一个问题是:
- 两个元素会出现相同的哈希值,至于为什么可以参考其他博客。
当出现哈希值相同时,这两个元素就会放进链表里面,比如a和b的哈希值都是95533,a和b就会放进链表里面。
但是
- 如果数据很多,散列表固定,那么就会造成数据太密集,同时链表就会很长,造成查询和插入次数多,造成性能下降。
- 如果增加散列表的长度,而要存储的数据并不多,就会造成空间的浪费。
为了合理解决这个问题,就有了负载因子的概念:
负载因子=填入表中元素/散列表的长度
通俗理解负载因子就是告诉散列表什么时候该扩容了。
比如,我们知道初始的HashMap初始容量为16,如果负载因子为1,即16*1=16,等容量完全占用以后才会扩容,那么就会增加时间查询成本。
负载因子过高就是第一种情况,造成性能下降;如果负载因子低就会造成空间的浪费,一般来说负载因子为0.75时能效比最大。
不可以存储相同元素原理
这里最主要的是两个方法:hashcode()和equals()。
当往里面存储元素时,首先会调用hashcode()方法,计算哈希值,然后判断哈希表中有没有这个值,如果没有那么直接储存,如果有,即发生了哈希冲突,然后再调用equals方法判断所存储的元素和相同哈希值的元素是否一样,如果不同,则将新的也进行存储,如果相同,则不存储。