Java之集合(十五)Set综述
转载请注明源出处:http://www.cnblogs.com/lighten/p/7427554.html
1.前言
原本按照顺序应该是list、queue然后就是set的讲解,但是因为set的实现比较容易,但是其容易是建立在map的实现之上才容易的,所以先讲解的map。现在对于set集合,就一次全部介绍完。Set集合特点就是没有重复的内容,其实现是通过map的键来实现的。
2.HashSet

HashSet的结构就是持有一个HashMap,map的键就是Set的内容,值全部是PRESENT这个对象。

构造方法都是与HashMap基本一致。
public Iterator<E> iterator() {
return map.keySet().iterator();
}
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.isEmpty();
}
public boolean contains(Object o) {
return map.containsKey(o);
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
public void clear() {
map.clear();
}
其它的方法实在没什么可说明的,都是map的相关方法,看看就可以了。
3.LinkedHashSet
LinkedHashSet继承自HashSet,其构造方法调用的都是父类HashSet的构造方法:

可以看出其入参dummy是没有什么用的,只是用来区分调用的是父类的哪个构造参数而已,值是什么无所谓,最终使用的是LinkedHashMap。其它的方法都是父类的方法。也没有什么可说的。顺便一提,LinkedHashMap的特性是其值是有序的,所以LinkedHashSet的迭代器也是有序的,默认是insert顺序,而不是access顺序,具体见LinkedHashMap那章介绍。
4.TreeSet
LinkedHashSet只能按照先后顺序来进行排序,TreeSet则是按照比较器给的比较规则进行从小到大排序。其实现也就是借助于TreeMap。

和HashSet的过程基本一致,实现也都是借助TreeMap的相关方法,所以也没有必要介绍了。
5.EnumSet
EnumSet的实现有些不一样,其并没有使用EnumMap,而是自己实现。这个类还是一个抽象类,里面的方法全是静态方法。

数据结构就一个枚举类的Class对象,和该枚举类的枚举实例。其构造方法是default域,我们没有办法进行直接创建。不过其静态方法提供的创建对象的能力。主要分为两个方法:noneOf和allOf。


noneOf的含义有些让人误解,因为枚举实例都放入了EnumSet中啊,为什么还称作是空?实际上仔细看就会明白,这个构造方法中并没有size等方法,所以虽然数组中有内容,但是却返回的大小都是0。allOf调用了抽象方法addAll(),也仅仅是改变了数量而已。先注意,枚举类的实例个数是影响了具体的类。<=64个的时候,使用的是RegularEnumSet,大于的时候是JumboEnumSet。

初看RegularEnumSet的源码会一脸懵逼,不是说是addAll是计数吗?为什么是位运算?实际上我们要明确一点,枚举类的删除添加修改等操作并不是真正的这么做了,而是打了一个标记而已。这也就解释了RegularEnumSet为什么必须枚举长度小于等于64,因为long类型只能表示64位。超过64位long不能再表示,所以使用另一个类JumboEnumSet来处理,其有个与实例对应的标志位数组(这个数组也不是一般的数组,本质上还是充分利用了long的位数,并没有一个数组位表示一个实例)和计数字段size来处理。
其它的添加,删除,获取的逻辑都是基于其标志位的内容来处理的,实际上枚举类的实例数组并没有变化。处理逻辑就不再描述,按照位运算一个个去尝试就可以了。RegularEnumSet的long标志表示是从右边开始算第0位,JumboEnumSet的标志位数组long[]的结构是,前64个元素标志位用long数组的第一个表示,和RegularEnumSet实现一样,从右到左计数,再64个用数组中第2个表示,也是从右到左。
RegularEnumSet:00000000 00000000 00000000 00001111
对应枚举实例下标:63 3210
JumboEnumSet:long[] 数组长度为2
long[0]
11111111 11111111 11111111 11111111
对应枚举实例下标: 63 0
long[1]
00000000 00000000 00000000 00001111
对应枚举实例下标: 127 64
Java之集合(十五)Set综述的更多相关文章
- Java中的集合(十五) Iterator 和 ListIterator、Enumeration
Java中的集合(十五) Iterator 和 ListIterator.Enumeration 一.Iterator (一).简介 Iterator 是一个接口,它是集合的迭代器.集合可以通过Ite ...
- Java进阶(二十五)Java连接mysql数据库(底层实现)
Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了.现在需要使用java完成一个实验,其中涉及到java连接数据库.让自己来写,记忆中已无从搜 ...
- Java进阶(三十五)java int与integer的区别
Java进阶(三十五)java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象 ...
- “全栈2019”Java多线程第二十五章:生产者与消费者线程详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第十五章:当后台线程遇到finally
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java异常第十五章:异常链详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- “全栈2019”Java第八十五章:实现接口中的嵌套接口
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 201671010140. 2016-2017-2 《Java程序设计》java学习第十五周
java学习第十五周 Java的GUI界面设计,框架以及主要部件填充,归置,布局管理,在第十一章和第十二章进行了系统的学习,在这两章的知识奠基下,可以简单的构造一个GUI用户界面,在两周的学习后,可以 ...
- “全栈2019”Java第七十五章:内部类持有外部类对象
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
随机推荐
- hdu - 1072(dfs剪枝或bfs)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072 思路:深搜每一个节点,并且进行剪枝,记录每一步上一次的s1,s2:如果之前走过的时间小于这一次, ...
- WriteableBitmap(三) 扩展
backbuffer使用您在创建WriteableBitmap时指定的像素格式,还有一个BackBufferStride属性,您可以使用它来创建一个合适的存储映射函数. 添加一些方法来设置和获取特定情 ...
- Codeforces777C Alyona and Spreadsheet 2017-05-04 17:46 103人阅读 评论(0) 收藏
C. Alyona and Spreadsheet time limit per test 1 second memory limit per test 256 megabytes input sta ...
- 图形与游戏中3D数学基础的说明
1.左手坐标系与右手坐标系没有好坏之分,不同的研究领域和不同的背景下,选择不同的坐标系:传统计算机图形学采用“左手坐标系”,线性代数则倾向于使用右手坐标系 坐标系由坐标轴与坐标原点组成.原点定义坐标系 ...
- CF1096D Easy Problem(DP)
题意:给出一个字符串,去掉第i位的花费为a[i],求使字符串中子串不含hard的最小代价. 题解:这题的思路还是比较套路的, dp[i][kd]两维,kd=0表示不含d的最小花费,1表示不含rd ...
- iOS Development和iOS Distribution有什么区别
http://zhidao.baidu.com/link?url=T9od33JuA7jjxzfyV-wOjuVLSNUaqpc9aoCu2HjfYfHBuRLW1CNDii0Bh9uvG6h-GeJ ...
- java keytool生成ssl加密密钥
教程:http://www.cnblogs.com/getherBlog/p/3930317.html 其中用到几个命令: keytool -genkeypair -alias certificate ...
- linux系统编程之信号(五):信号集操作函数,信号阻塞与未决
一,信号集及相关操作函数 信号集被定义为一种数据类型: typedef struct { unsigned long sig[_NSIG_WORDS]: } sigset_t 信号集用来描述信号的集合 ...
- 对Cookie和Session的理解
本篇文章系自己总结经验,如果有朋友感觉哪里有问题,欢迎留言评论,谢谢~! Cookie和Session的产生背景: 在动态页面里面,每个变量都是有有效期的,所有的变量的最大生命周期就是一个脚本的周期( ...
- dorado-SplitSpanel控件
1.这是一个界面布局控件 2.分为SideControl边区域和MainControl主区域 3.常用属性 3.1 collapsed:打开页面时,边区域是否显示 3.2 position:边区域占总 ...