转载请注明源出处: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综述的更多相关文章

  1. Java中的集合(十五) Iterator 和 ListIterator、Enumeration

    Java中的集合(十五) Iterator 和 ListIterator.Enumeration 一.Iterator (一).简介 Iterator 是一个接口,它是集合的迭代器.集合可以通过Ite ...

  2. Java进阶(二十五)Java连接mysql数据库(底层实现)

    Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了.现在需要使用java完成一个实验,其中涉及到java连接数据库.让自己来写,记忆中已无从搜 ...

  3. Java进阶(三十五)java int与integer的区别

    Java进阶(三十五)java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象 ...

  4. “全栈2019”Java多线程第二十五章:生产者与消费者线程详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  5. “全栈2019”Java多线程第十五章:当后台线程遇到finally

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. “全栈2019”Java异常第十五章:异常链详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  7. “全栈2019”Java第八十五章:实现接口中的嵌套接口

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  8. 201671010140. 2016-2017-2 《Java程序设计》java学习第十五周

    java学习第十五周 Java的GUI界面设计,框架以及主要部件填充,归置,布局管理,在第十一章和第十二章进行了系统的学习,在这两章的知识奠基下,可以简单的构造一个GUI用户界面,在两周的学习后,可以 ...

  9. “全栈2019”Java第七十五章:内部类持有外部类对象

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

随机推荐

  1. 37 The Benefits of Cutting Salt 减少盐分摄取量的益处

    The Benefits of Cutting Salt 减少盐分摄取量的益处 ①Just when you had figured out how to manage fat in your die ...

  2. 安装memcache服务

    d:\tools\memcache\setup\memcached -d install

  3. DIV+CSS实战(三)

    一.说明 在上篇博客<DIV+CSS实战(二)>中,实现了头部以及Tab标签卡,下面开始实现内容区域,要实现的效果如下: 二.内容最外层的设计(边框) 给最外层加边框,并且设置高度随着里面 ...

  4. MFC框架仿真<一>

    #include "my.h" CMyWinApp theApp;/*起点->全局对象*/ void main() { CWinApp* pApp = AfxGetApp() ...

  5. Js中 关于top、clientTop、scrollTop、offsetTop

    网页可见区域宽: document.body.clientWidth; 网页可见区域高: document.body.clientHeight; 网页可见区域宽: document.body.offs ...

  6. springMVC 开涛 Controller接口控制器

    通过注解实现控制器类,所以不用看Controller接口了.把之前的笔记保存下. 笔记(图片):http://pan.baidu.com/s/1mgMNDna 第三章看不太懂,3.2 3.3.只了解到 ...

  7. cheerio笔记

    不会的东西,再简单都是难:会的东西,再难都是简单. 给自己写的,写的通俗易懂. cheerio:在node服务端,解析网页,是jquery的核心,去除了DOM中不一致的地方. 先获得网页的源码,再通过 ...

  8. Java核心编程快速学习(转载)

    http://www.cnblogs.com/wanliwang01/p/java_core.html Java核心编程部分的基础学习内容就不一一介绍了,本文的重点是JAVA中相对复杂的一些概念,主体 ...

  9. Linux SNAT/DNAT简单理解与案例分析。

      在计算机网络中,网络地址转换(Network Address Translation,缩写为NAT),也叫做网络掩蔽或者IP掩蔽(IP masquerading),是一种在IP数据包通过路由器或防 ...

  10. 常用kubectl命令总结

    command kubectl kubectl 输出格式 显示Pod的更多信息 kubectl get pod <pod-name> -o wide 以yaml格式显示Pod的详细信息 k ...