HashSet集合存储数据的结构(哈希表)
import java.util.HashSet; //存在util包内,要导包,
哈希值:一个十进制的整数,由系统给出,是一个逻辑地址,并非实际的物理地址
jak1.8版本之前:哈希表=数组+链表
jdk1.8版本之后:
哈希表=数组+链表
哈希表=数组+红黑树(查询速度极快)
哈希表的特点是速度快
当有数据要存储到集合的时候,会先计算元素的哈希值(元素在数组中的存储位置)
HashSet是Set接口的一个实现类,Set接口是Collection类的子类
HashSet集合的其他特点:
哈希表是无序的,而且没有索引,所以只可以用迭代和增强for来遍历
存入的元素不能重复
底层是哈希表结构
HashSet
为什么说存入的元素不能重复:
原理:
在Object类里面有一个 native hashCode();方法可以返回对象的哈希值,在要存储元素之的时候即进行add();方法,add方法会调用hashCode方法和equals方法判断元素是否重复。
例子如下:
![5e130471d622954aa1551f96189ff1a4.png](https://img-blog.csdnimg.cn/img_convert/5e130471d622954aa1551f96189ff1a4.png)
在这个例子里面
Set集合在调用add方法的时候它会调用元素的HashCode()方法和equals()方法判断元素是否重复
add方法调用s1的hashCode方法计算字符串"abc"的哈希值 96354
在集合里面没有96354就把这个哈希值存入到数组中且把s1字符串挂到这个数组对应的索引下面
add调用s2的hashCode方法计算哈希值,发现数组存在了96354这个哈希值,就会发生哈希冲突,然后调用equals方法s2.equals(s1)
返回ture 两个元素哈希值相同且认定两个元素相同,,就不会把s2存储到集合中
可以同时存入重地和通话完全是因为 在第二步中 重地.equals("通话")不相等返回了false 从而认定元素不相同
发现hash冲突才会调用equals方法
代码如下 :
import java.util.HashSet;
public class Demo03HashSetSaveString {
public static void main(String[] args) {
HashSet<String> set=new HashSet<>();//创建一个HashSet对象,不能够多态
String s1=new String("abc");
String s2=new String("abc");
set.add(s1);
set.add(s2);
set.add("重地");
set.add("通话");
set.add("abc");
for(String a:set){
System.out.println(a);
}
}
}
这里面要特别提醒:字符串里面 “重地”和“通话”的哈希值是一样的
下图为一个HashSet数组的结构和三个元素,演示存储的过程
![f48f33da24574a82f98cb90c8f9a0d84.png](https://img-blog.csdnimg.cn/img_convert/f48f33da24574a82f98cb90c8f9a0d84.png)
首先存入字符串“abc”;通过hashCode方法发现数组里没有96354这个哈希值,将这个哈希值存入数组,然后将元素"abc"以链表的方式连接在对应的哈希值数组下
![v2-d1b5d22425f342000d7215fdda690ea2_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=3a9c3581-9131-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-d1b5d22425f342000d7215fdda690ea2_b.jpg)
然后重复操作同样存入元素"重地";
![ab8669f47876f876b1ac8e4fc2dd4434.png](https://img-blog.csdnimg.cn/img_convert/ab8669f47876f876b1ac8e4fc2dd4434.png)
最后,存入元素“通话”,在调用方法hashCode返回哈希值的时候,发现数组中已经存在117935这个哈希值,要调用equals方法比较元素“重地”和“通话”,若返回false,存入“通话”,若返回ture,放弃存储。很明显,“通话”.equals("重地")返回false,因为哈希值一样所以“通话”以链表的形式挂在“重地”下面,形成链表
![08e087a93da009de7a4a12da466b3604.png](https://img-blog.csdnimg.cn/img_convert/08e087a93da009de7a4a12da466b3604.png)
哈希表=数组+红黑树(查询速度极快)又是怎么回事呢?
这是当如果表中同一哈希值下挂的元素超过8个就会转换成对应的红黑树(这样查询的速度就超级快)
这就是我所认识的HashSet希望对你有帮助