value 值,使用 HashSet的开发者只需关注于需要插入的 key,屏蔽了
HashMap 的 value
文章插图
上图可以观察到每个 Entry 的 value 都是 PRESENT 空对象,我们就不用再理会它了 。
HashSet 在 HashMap 基础上实现,所以很多地方可以联系到 HashMap:
- 底层数据结构:HashSet 也是采用数组 + 链表 + 红黑树实现
- 线程安全性:由于采用 HashMap 实现,而 HashMap 本身线程不安全,在HashSet 中没有添加额外的同步策略,所以 HashSet 也线程不安全
- 存入 HashSet 的对象的状态最好不要发生变化,因为有可能改变状态后,在集合内部出现两个元素 o1.equals(o2),破坏了 equals 的语义 。
LinkedHashSetLinkedHashSet 的代码少的可怜,不信我给你我粘出来
文章插图
少归少,还是不能闹,LinkedHashSet 继承了 HashSet,我们跟随到父类 HashSet 的构造方法看看
HashSet(int initialCapacity, float loadFactor, boolean dummy) {this.map = new LinkedHashMap(initialCapacity, loadFactor);}
发现父类中 map 的实现采用 LinkedHashMap,这里注意不是 HashMap,而LinkedHashMap 底层又采用 HashMap + 双向链表 实现的,所以本质上
LinkedHashSet 还是使用 HashMap 实现的 。
LinkedHashSet -> LinkedHashMap -> HashMap + 双向链表
文章插图
image.png
而 LinkedHashMap 是采用 HashMap 和双向链表实现的,这条双向链表中保存了元素的插入顺序 。所以 LinkedHashSet 可以按照元素的插入顺序遍历元素,如果你熟悉 LinkedHashMap,那 LinkedHashSet 也就更不在话下了 。
关于 LinkedHashSet 需要注意几个地方:
- 它继承了 HashSet,而 HashSet 默认是采用 HashMap 存储数据的,但是 LinkedHashSet 调用父类构造方法初始化 map 时是 LinkedHashMap 而不是 HashMap,这个要额外注意一下
- 由于 LinkedHashMap 不是线程安全的,且在 LinkedHashSet 中没有添加额外的同步策略,所以 LinkedHashSet 集合也不是线程安全的
TreeSetTreeSet 是基于 TreeMap 的实现,所以存储的元素是有序的,底层的数据结构是数组 + 红黑树 。
文章插图
而元素的排列顺序有2种,和 TreeMap 相同:自然排序和定制排序,常用的构造方法已经在下面展示出来了,TreeSet 默认按照自然排序,如果需要定制排序,需要传入 Comparator 。
public TreeSet {this(new TreeMap<E,Object>);}publicTreeSet(Comparator<? super E> comparator) {this(new TreeMap<>(comparator));}
TreeSet 应用场景有很多,像在游戏里的玩家战斗力排行榜public class Player implements Comparable<Integer> {public String name;public int score;@Overridepublic int compareTo(Student o) {return Integer.compareTo(this.score, o.score);}}public static voidmain(String[] args) {Player s1 = new Player("张三", 100);Player s2 = new Player("李四", 90);Player s3 = new Player("王五", 80);TreeSet<Player> set = new TreeSet;set.add(s2); set.add(s1); set.add(s3);System.out.println(set);}// [Student{name='王五', score=80}, Student{name='李四', score=90}, Student{name='张三', score=100}]
对 TreeSet 介绍了它的主要实现方式和应用场景,有几个值得注意的点 。- TreeSet 的所有操作都会转换为对 TreeMap 的操作,TreeMap 采用红黑树实现,任意操作的平均时间复杂度为 O(logN)
- TreeSet 是一个线程不安全的集合
- TreeSet 常应用于对不重复的元素定制排序,例如玩家战力排行榜
注意:TreeSet 判断元素是否重复的方法是判断 compareTo 方法是否返回0,而不是调用 hashcode 和 equals 方法,如果返回 0 则认为集合内已经存在相同的元素,不会再加入到集合当中 。
文章插图
List 接口
List 接口和 Set 接口齐头并进,是我们日常开发中接触的很多的一种集合类型了 。整个 List 集合的组成部分如下图:
文章插图
List 接口直接继承 Collection 接口,它定义为可以存储重复元素的集合,并且元素按照插入顺序有序排列,且可以通过索引访问指定位置的元素 。常见的实现有:ArrayList、LinkedList、Vector 和 Stack
推荐阅读
- 已有两种太空探测器飞出我们的太阳系 飞往太阳系外的探测器
- 生科医学|全国疫情形势呈逐渐企稳态势!上海两区首日达到社会面清零目标
- 两只耳朵配不一样的助听器,助听器需要两个耳朵都配吗??
- 前端开发和后端开发的区别?这两者哪个更累?
- 如何将两个pdf合并?合并pdf的快捷方法分享
- 验孕纸两条杠是怎么回事呢
- 喝白酒时,讲究这4个“最佳”,健康饮酒醉得慢,让你多喝二两半
- 减腰两边的赘肉怎么做?
- 水陆两栖动物名字大全 水陆两栖的动物是什么动物
- 花钱学Python?不存在的!一份大纲两个网站外加搜索,足矣