Github:https://github.com/yihonglei/jdk-source-code-reading
HashTable 源码
HashMap 源码
ConcurrentHashMap 源码
HashSet 是专用来存放对象的 HashMap,底层用的 HashMap 数据结构存储。
很困惑,HashMap 不也能存储对象吗?为毛还要 HashSet 呢?应用场景是什么,
这个技术存在的价值是什么?下面看看源码吧!
package com.jpeony.collection.set; import java.util.HashSet; import java.util.Set; /** * 存放不重复对象。 * * @author yihonglei */ public class HashSetTest { public static void main(String[] args) { // add Set<String> set = new HashSet<>(); set.add("a"); set.add("b"); set.add("c"); set.add("d"); set.add("e"); // remove set.remove("e"); // print for (String str : set) { System.out.println(str); } } }
运行结果
重点分析 add()方法。
public HashSet() { // 默认 HashMap 存储 map = new HashMap<>(); }
// Dummy value to associate with an Object in the backing Map private static final Object PRESENT = new Object(); public boolean add(E e) { return map.put(e, PRESENT)==null; }
元素的添加底层是 HashMap 的 put 方法,但是,value 每次 add 都会创建一个空对象。
1、我们发现 HashSet 的 add 底层是 HashMap 的 put,只是每次 add 的 value 都是创建一个
哑结点对象,这么说 HashSet 是添加一组数据集合,是否可以用 ArrayList 替代?
有些场景下,不能,从 HashSet 的源码可以看出,HashSet 存储一组没有重复元素的数组,
支持按照对象进行查找元素,就凭这两点,ArrayList 就做不到,ArrayList 不能自然保证元素
的不重复,并且,ArrayList 没法指定对象查找,时间复杂度是 O(n),而 HashSet 的时间复杂
度是 O(1),对于 jdk 7 来说,HashMap 最坏退到链表查找 O(n),在 jdk8,一般退到链表O(n),
大数据量时退到红黑树O(logn),总体来说,根据对象查找元素,HashSet 时间复杂度优于数组。
2、既然有了 HashMap,为啥还需要 HashSet?HashMap 专注于存储 k-v 结构,而 HashSet
则专注于存储 对象,实际中 HashSet 是不是没怎么用过?其实各种技术源码底层用得还是比较
多的。
JDK 线程池,工作线程的存储列表。
主要是方便进行工作线程对象的添加和移出。
RocketMQ 注册 Broker 到 NameServer 时存储 broker 集群名称。
主要用于存储不重复对象集合,并能根据对象快速进行删除。