HashSet底层原理
HashSet
是最常用的Set
集合之一,可以保证元素的唯一性。
- 底层原理
HashSet
底层完全就是在HashMap
的基础上包了一层,只不过存储的时候value
是默认存储了一个Object
的静态常量,取的时候也是只返回key
,所以看起来就像List
一样。 -
构造方法
可以看到四个构造方法都是初始化一个
HashMap
,初始化的容量和装填因子也是直接用的HashMap
的默认配置。private transient HashMap<E,Object> map; public HashSet() { map = new HashMap<>(); } public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); } public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); }
-
add()/remove()/contains()方法
可以看到这三个方法都是直接调用的
HashMap
的实现。public boolean add(E e) { return map.put(e, PRESENT)==null; } public boolean remove(Object o) { return map.remove(o)==PRESENT; } public boolean contains(Object o) { return map.containsKey(o); }
-
保证唯一性
HashSet
是调用的HashMap
的put()
方法,而put()
方法中有这么一行逻辑,如果哈希值
和key
都一样,就会直接拿新值覆盖旧值,而HashSet
就是利用这个特性来保证唯一性。if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p;
所以在存放对象的时候需要重写
hashCode()
和equals()
方法,因为就是用这两个方法来判断唯一性的,否则就会出现下面这样的情况,创建两个属性一样的对象,放入HashSet
中会发现重复了,那是因为创建两个对象肯定哈希值是不一样的,所以需要自己重写hashCode()
和equals()
。public class TestVo { int id; String name; public TestVo(int id, String name) { this.id = id; this.name = name; } @Override public String toString() { return "TestVo{" + "id=" + id + ", name='" + name + '\'' + '}'; } } public static void main(String[] args){ HashSet set = new HashSet(); TestVo testVo1 = new TestVo(1,"a"); TestVo testVo2 = new TestVo(1,"a"); set.add(testVo1); set.add(testVo2); Iterator<TestVo> iterator = set.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } } // 输出结果 TestVo{id=1, name='a'} TestVo{id=1, name='a'}
重写
hashCode()
和equals()
方法,都基于id
来判断,这样重复`
`id的就不会重复存入了,所以存入对象的时候是可以自己设置按什么规则来去重的。@Override public int hashCode() { return id; } @Override public boolean equals(Object obj) { return obj.equals(id); } } // 输出结果 TestVo{id=1, name='a'}
总结
HashSet
底层原理完全就是包装了一下HashMap
HashSet
的唯一性保证是依赖与hashCode()
和equals()
两个方法,所以存入对象的时候一定要自己重写这两个方法来设置去重的规则。- 因为底层是
HashMap
,而存储的又是key
,所以没有get()
方法来直接获取,只能遍历获取。
本文摘自,如有侵权,请联系我!!!
分类:
java集合
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构