概述
是通过 HashCode 算法实现的一个线性集合,特点就是 不可重复,长度可变,无序 的集合
特点:不可重复
不是线程安全的
原理:HashMap
判断元素是否重复
先判断两个对象的
hashCode()方法返回值是否相同,即存储的位置;然后再判断两个对象的
equals()方法返回值是否为true,即存储实际的对象值
例子
public static void main(String[] args) {
Set set = new HashSet();
set.add("抖音");
set.add("快手");
set.add("抖音");
System.out.println(set.size());
set.add("快手");
System.out.println(set.size());
System.out.println(set.size());
for(Object obj : set){
System.out.print(obj + "\t");
}
}
两个是相同的,会被去重
输出的顺序是通过hashCode计算出来的,所以特殊的常量会固定
原理
是通过 HashMap 实现的。
HashSet 中add()的元素作为 HashMap 的key
创建 Object 对象,这个对象作为 HashMap 中的value
不同的版本实现
在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。
简单的来说,哈希表是由数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,如下图所示。
看到这张图就有人要问了,这个是怎么存储的呢?
为了方便大家的理解我们结合一个存储流程图来说明一下:
总而言之,JDK1.8引入红黑树大程度优化了HashMap的性能,那么对于我们来讲保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。