TOP

Java集合 HashSet的原理及常用方法
2019-08-14 00:08:28 】 浏览:45
Tags:Java 集合 HashSet 原理 常用 方法


HashSet有几个重载的构造方法,我们来看一下


通过上面的源码,我们发现了HashSet就TM是一个皮包公司,它就对外接活儿,活儿接到了就直接扔给HashMap处理了。因为底层是通过HashMap实现的,这里简单提一下:


HashMap的数据存储是通过数组+链表/红黑树实现的,存储大概流程是通过hash函数计算在数组中存储的位置,如果该位置已经有值了,判断key是否相同,相同则覆盖,不相同则放到元素对应的链表中,如果链表长度大于8,就转化为红黑树,如果容量不够,则需扩容(注:这只是大致流程)。


如果对HashMap原理不太清楚的话,可以先去了解一下


HashMap原理(一) 概念和底层架构


HashMap原理(二) 扩容机制及存取原理


HashSet的add方法时通过HashMap的put方法实现的,不过HashMap是key-value键值对,而HashSet是集合,那么是怎么存储的呢,我们看一下源码


看源码我们知道,HashSet添加的元素是存放在HashMap的key位置上,而value取了默认常量PRESENT,是一个空对象,至于map的put方法,大家可以看HashMap原理(二) 扩容机制及存取原理



HashSet的remove方法通过HashMap的remove方法来实现


removeTreeNode方法具体实现可参考 TreeMap原理实现及常用方法


afterNodeRemoval方法具体实现可参考LinkedHashMap如何保证顺序性


HashSet作为集合,有多种遍历方法,如普通for循环,增强for循环,迭代器,我们通过迭代器遍历来看一下


打印出来的结果如何呢?


意料之中吧,HashSet是通过HashMap来实现的,HashMap通过hash(key)来确定存储的位置,是不具备存储顺序性的,因此HashSet遍历出的元素也并非按照插入的顺序。


按照我前面的规划,应该每一块主要的内容都单独写一下,如集合ArrayList,LinkedList,HashMap,TreeMap等。不过我在写这篇关于HashSet的文章时,发现有前面对HashMap的讲解后,确实简单,HashSet就是一个皮包公司,在HashMap外面加了一个壳,那么LinkedHashSet是否就是在LinkedHashMap外面加了一个壳呢,而TreeSet是否是在TreeMap外面加了一个壳?我们来验证一下


最开始的结构图已经提到了LinkedHashSet是HashSet的子类,我们来看源码


上面就是LinkedHashSet的所有代码了,是不是感觉智商被否定了,这基本上没啥东西嘛,构造器还全部调用父类的,下面就是其父类HashSet的对此的构造方法


大家也看出来,和我们的猜测一样,没有深究下去的必要了。如果有兴趣可以看看LinkedHashMap如何保证顺序性


确实如我们所猜测,TreeSet也完全依赖于TreeMap来实现,如果有兴趣可以看看TreeMap原理实现及常用方法


本来想三章的内容,一章就算完了,虽然Set实现有点赖皮,毕竟他祖辈是Collection而不是Map,在Map的实现类上穿了一层衣服就成了Set,然后出于某种目的埋伏在Collection中,哈哈,开个玩笑,本文主要介绍了HashSet的原理以及主要方法,同时简单介绍了LinkedHashSet和TreeSet,若有不对之处,请批评指正,望共同进步,谢谢!



Java集合 HashSet的原理及常用方法 https://www.cppentry.com/bencandy.php?fid=54&id=228519

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Java枚举类型enum深入理解 下一篇LinkedHashMap如何保证顺序性