首页 > 编程语言 >Java 集合框架4:Set

Java 集合框架4:Set

时间:2022-12-01 19:35:25浏览次数:47  
标签:Set Java HashSet 元素 EnumSet BitSet 集合

目录

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

相关文章

  • JavaScript Everywhere All In One
    JavaScriptEverywhereAllInOnetagsjsNode.jsExpress.jsMongoDBApolloClientGraphQLAPIJWTOAuth2.0ReactReactNativeElectronhttps://github.com/......
  • lintcode:Subsets
    Givenasetofdistinctintegers,returnallpossiblesubsets.ChallengeCanyoudoitinbothrecursivelyanditeratively?1.18sclassSolution{public:/**......
  • lintcode: Subsets II
    Givenalistofnumbersthatmayhasduplicatenumbers,returnallpossiblesubsets1.先排序;再按求Subsets一样的做法,只是添加前检查是否已经存在。耗时171mscla......
  • AlmaLinux 9.1中安装java11
     001、系统[[email protected]]#cat/etc/redhat-releaseAlmaLinuxrelease9.1(LimeLynx)  002、测试java命令[root@PC1test]#javabash:java:c......
  • List集合转换成数组
    我现在有个需求:将File集合转换成MultipartFile数组结构然后我就开始在网上开启了List转换到数组之旅。首先来看一个例子ArrayList<String>list=newArrayList<......
  • 对于从1到N的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的。
    #include<iostream>#include<vector>#include<cstdlib>usingnamespacestd;constintMax=10000;classDynamicClass{private:intn;//n表示{1,2,3,...n}longs......
  • Java文件操作实例浅析
    Java文件操作实例浅析1.   实例一:创建文件和目录在java.io包中有一个专门用于文件操作的类File类。此类提供了文件很多操作,如创建文件、删除文件、创建目录、删除目录等......
  • C、C++、Java语言中异常处理机制浅析
    C、C++、Java语言中异常处理机制浅析一、    异常处理(ExceptionalHandling)概述1.    异常处理异常处理又称异常错误处理,它提供了处理程序运行时出现任何意外或......
  • java安全组放行
    使用JAVA虚拟机,被安全阻止   解决:控制面板找到JAVA应用,配置JAVA   选择安全属性,编辑站点列表,并点击确定完成修改  ......
  • JAVA整合阿里云OSS/VUE上传阿里云OSS
    前言今天码帮帮系统已经整合到上传项目案例的功能了,这里有一些图片资源需要上传,之前做项目对接过七牛云,也有使用过阿里云的视频点播服务,不过这次对接阿里云的OSS确实有点......