🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 概述 此类实现Set接口,由哈希表支持(实际上是一个 HashMap集合)。HashSet集合不能保证的迭代顺序与元素存储顺序相同 . 哈希表是单向链 . HashSet集合,采用哈希表结构存储数据,保证元素唯一性的方式依赖于:hashCode()与equals()方法。 ### 实例 ~~~ HashSet<String> set = new HashSet<String>(); set.add("我"); set.add("爱"); set.add("你"); Iterator<String> it = set.iterator(); while(it.hasNext()){ System.out.println(it.next()); } ~~~ 结果 ~~~ 你 我 爱 ~~~ ### 数据结构 哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。 当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。 总结:保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。 ![](https://box.kancloud.cn/7bc010e5d54296f10d7cdfbc7d8f7794_1260x590.png) ### 说明 它是线程不安全的 . HashSet初始容量是16 . 加载因子是0.75 . 如果容量超过16 ,name就会生成新的数组,并和原有的HashSet进行复制 . 这样就会降低性能 . ### 字符串对象的哈希值 对象的哈希值,是一个十进制的整数 . 是父类Object去完成的 ,是一个本地方法 . 如果我们不重写父类方法,每次运行**结果是不同的十进制整数值** . 哈希值是存储到HashSet集合的依据 . ~~~ String s1 = new String("abc"); String s2 = new String("abc"); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); //哈希值是一致的 ~~~ 两个对象的内存地址是不一致的,但是哈希值是一致的,为什么呢 ? 因为String类重写了父类的方法, 它有自己计算哈希值的方式 . ### 哈希表的存储过程 ~~~ HashSet<String> set = new HashSet<String>(); set.add(new String("hello world")); set.add(new String("hello world")); set.add(new String("happy")); set.add(new String("happy")); System.out.println(set.toString()); ~~~ 结果 ~~~ [happy, hello world] ~~~ 1. 调用每个存储对象的哈希值 . 2. 集合在容器内寻找有没有相同的哈希值对象 . 3. 如果找到有相同哈希值的对象, 将后放入集合的的对象调用equals()方法和第一个进行比较 . 4. 如果两个对象,哈希值一致,equals()方法返回值是true , 集合判断元素已经重复 . 5. 对于判定元素不重复的存储方式是让前一个对象记住后一个对象的内存地址, 和桶状类似 . 6. 简单说HashSet只能存放不同元素的机制就是先比较哈希值,再比较元素内容是否相等 . ### 哈希表存储自定义对象