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第 ...
随机推荐
- json、JSONObject、JSONArray的应用
type.java package jiekou.duixiang; import java.text.ParseException;import java.text.SimpleDateFormat ...
- python corrcoef
该函数得到相关系数矩阵. 例子: vc=[1,2,39,0,8] vb=[1,2,38,0,8] print mean(multiply((vc-mean(vc)),(vb-mean(vb))))/( ...
- yum 常用命令
yum是一个用于管理rpm包的后台程序,用python写成,可以非常方便的解决rpm的依赖关系.在建立好yum服务器后,yum客户端可以通过 http.ftp方式获得软件包,并使用方便的命令直接管理. ...
- VS2010编译错误:是否忘记了向源中添加“#include "stdafx.h
VS2010编译错误:是否忘记了向源中添加“#include "stdafx.h 编译提示:fatal error C1010: 在查找预编译头时遇到意外的文件结尾.是否忘记了向源中添加“# ...
- c++ 64位int
转自:https://www.byvoid.com/blog/c-int64 C/C++的64位整型 在C/C++中,64为整型一直是一种没有确定规范的数据类型.现今主流的编译器中,对64为整型的支持 ...
- node express session
在express4.0版本以上,需要单独增加session模块:express-session:https://www.npmjs.com/package/express-session 具体做法是, ...
- Media Queries简单案例一
案例一: 1 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" ...
- 在ContextLoaderListener中使用注解注入的类和job中使用注解注入的类
场景:在ContextLoaderListener子类中加载job,为JobFactory的实现类声明@Component后,在ContextLoaderListener子类中为scheduler设置 ...
- 设计模式之迭代器模式(Iterator Pattern)
一.什么是迭代器模式? 用迭代器来封装集合对象的遍历细节,使调用者能够通过统一的接口来实现对集合的遍历 迭代器也给集合对象提供了一定的保护,想要遍历集合,直接调用迭代器的方法就好了,我们不知道也不必知 ...
- abp+angular+bootstrap-table的使用
问题 materialize与bootstrap框架样式冲突 问题描述 在abp模板项目中引入bootstrap-table,列设置为checkbox,checkbox无法显示. 使用firefox浏 ...