目录
Set
1.概述
Set 是一个不允许包含重复元素,或者说是不允许包含包含满足e1.equals(e2)
的两个元素。并且,至多包含一个 null 元素(有些实现类甚至不允许包含 null)。
Set 接口只包含从父接口继承来的方法,但它对构造函数、add、equals 和 hashCode 有着更强的限制。
2.SortedSet
SortedSet 的元素保持元素的升序,序列的顺序由自然序或者在 SortedSet 创建时指定的 Comparator 确定。
SortedSet 提供了额外的操作:
1.范围视图
subSet、headSet、tailSet 分别返回,Set 的 [fromElement, toElement) 范围视图。
以 subSet 方法为例,需要注意的是,subSet 与原 set 修改范围内的元素会相互影响,但修改范围外的元素会抛出异常:
2.端点
first 与 last 方法分别返回 Set 的最小、最大元素。
3.Comparator
返回 Comparator。使用自然排序时会返回 null。
3.实现
Java 提供了三种通用的 Set 实现:HashSet、TreeSet 和 LinkedHashSet。除此之外,还有 EnumSet、CopyOnWriteArraySet、BitSet 等。
HashSet
HashSet 是基于 HashMap 实现的。HashSet 的元素会被作为 map 的 key ,而 map 的 value 均为 HashSet 中的静态对象 PRESENT。
HashSet 所有构造方法中,默认的 capacity 为 16,load factor 为 0.75。
由于HashSet 的实现是通过 HashMap 的,HashSet 的大部分操作也是使用 HashMap 的方法。
除此之外,TreeSet 与 LinkedHashSet 也类似于 HashSet,通过 TreeMap 与 LinkedHashMap 实现。这三种 Map 实现原理可参见我另一篇博客:Java 集合框架5:Map。
EnumSet
EnumSet 是一个 Set 集合的抽象类,其有两个实现类 JumboEnumSet 和 RegularEnumSet。EnumSet 要求存入的元素的类型为同一枚举类型。
注意:JumboEnumSet 和 RegularEnumSet 并未有访问权限修饰符修饰,是 EnumSet 的私有实现。
EnumSet 是抽象类,使用静态工厂方法来代替构造方法。
以 of(E, E...) 方法为例,首先会根据 noneof 方法创建对应的 EnumSet 空实例(JumboEnumSet 或 RegularEnumSet),再向 EnumSet 实例添加 element。
根据枚举类元素个数,小于等于 64 (也就是 long 二进制位数),创造 RegularEnumSet 实例,否则创造 JumboEnumSet 实例。
为什么会有这样的设计?因为EnumSet 实现采用了高效的位向量。RegularEnumSet 是以一个 long 型的数中,二进制的 64 位的每一位来表示一个枚举中的元素,0 和 1 来表示有无。当枚举类元素个数大于 64 时,使用 JumboEnumSet,它使用 long 数组,以扩充表示枚举类元素的位的个数。
Set 的所有操作,都是在 elements 上进行位操作。
CopyOnWriteArraySet
CopyOnWriteArraySet 基于 CopyOnWrite 数组实现,与 CopyOnWriteArrayList 类似(参见我的另外一篇博客:Java 集合框架2:List)。CopyOnWriteSet 只适用于集合中的元素很少修改,经常被迭代的情况。CopyOnWriteArraySet 具有下面的性质:
- 非常适合在 Set 的大小保持很小,对集合的读操作远远多于改变操作。并且需要在多个线程环境进行无干扰(interleave)的迭代 。
- 它是线程安全的 。
- 改变操作(add、remove、set)代价昂贵,因为每次改变都需要重新复制一份底层的数组 。
- 迭代器并不支持 remove 方法
- 迭代操作非常的快速并且不会受到多个线程交错的干扰。迭代器是基于某个时间点的不可变的 snapshot。
BitSet
与 EnumSet 类似,BitSet 也是根据 long 的某位的布尔值,判断该位数值是否存在。
BitSet 使用 words 这个数组来存储信息。默认的构造函数创造长度为 1 的 words 数组,能存储 64 个信息。当指定信息长度时,words 数组长度为能存储信息长度的最小长度,表明最大能存储信息长度为 64 的整数倍。
BitSet 的所有操作也为位操作,但当 words 存储空间不够时,会进行扩容,策略为变为原来的两倍:
标签:Set,Java,HashSet,元素,EnumSet,BitSet,集合 From: https://www.cnblogs.com/meyok/p/16942441.html