JAVA HashSet

概述

是通过 HashCode 算法实现的一个线性集合,特点就是 不可重复,长度可变,无序 的集合
特点:不可重复

不是线程安全的

原理:HashMap

判断元素是否重复

  1. 先判断两个对象的 hashCode() 方法返回值是否相同,即存储的位置;

  2. 然后再判断两个对象的 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增加了红黑树部分)实现的,如下图所示。哈希表.png

看到这张图就有人要问了,这个是怎么存储的呢?

为了方便大家的理解我们结合一个存储流程图来说明一下:

哈希流程图.png

总而言之,JDK1.8引入红黑树大程度优化了HashMap的性能,那么对于我们来讲保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。


原文出处:/show_1EF4sL9lMmge.html