类似于HashMap和HashSet之间的关系,HashSet底层依赖于HashMap实现,TreeSet底层则采用一个NavigableMap来保存TreeSet集合的元素。但实际上,由于NavigableMap只是一个接口,因此底层依然是使用TreeMap来包含Set集合中的所有元素

下面是TreeSet类的部分源代码

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{

    // 使用NavigableMap的key来保存Set集合的元素
    private transient NavigableMap<E,Object> m;
    // 使用一个PRESENT作为Map集合的所有value
    private static final Object PRESENT = new Object();

    // 包访问权限的构造器,以指定的NavigableMap对象创建Set集合
    TreeSet(NavigableMap<E,Object> m) {
        this.m = m;马士兵
    }

    public TreeSet() {                                  // ①
        // 以自然顺序方式创建一个新的TreeMap,根据该TreeSet创建一个TreeSet
    this(new TreeMap<E,Object>());
    }

    public TreeSet(Comparator<? super E> comparator) {  // ②
        // 以定制顺序方式创建一个新的TreeMap,根据该TreeSet创建一个TreeSet
    // 使用该TreeMap的key来保存Set集合的元素
    this(new TreeMap<E,Object>(comparator));
    }

    public TreeSet(Collection<? extends E> c) {
        // 调用①号构造器创建一个TreeSet,底层以TreeMap保存集合元素
        this();
    // 向TreeSet中添加Collection集合c里的所有元素
        addAll(c);
    }

    public TreeSet(SortedSet<E> s) {
        // 调用②号构造器创建衣蛾TreeSet,底层以TreeMap保存集合元素
        this(s.comparator());
    // 向TreeSet中添加SortedSet集合s里的所有元素
    addAll(s);
    }

    public  boolean addAll(Collection<? extends E> c) {
        // Use linear-time version if applicable
        if (m.size()==0 && c.size() > 0 &&
        c instanceof SortedSet &&
            m instanceof TreeMap) {
        // 把c集合强制转换为SortedSet集合
            SortedSet<? extends E> set = (SortedSet<? extends E>) c;
        // 把m集合强制转换为TreeMap集合
            TreeMap<E,Object> map = (TreeMap<E, Object>) m;
            Comparator<? super E> cc = (Comparator<? super E>) set.comparator();
            Comparator<? super E> mc = map.comparator();
            // 如果cc和mc两个Comparator相等
            if (cc==mc || (cc != null && cc.equals(mc))) {
            // 把Collection中所有元素添加成TreeMap集合的key
                map.addAllForTreeSet(set, PRESENT);
                return true;
            }
        }
    // 直接调用父类的addAll()方法来实现
        return super.addAll(c);
    }
}

从上面代码可以看出,TreeSet的①号、②号构造器都是新建一个TreeMap作为实际存储Set元素的容器,而另外2个构造器则分别依赖于①号和②号构造器。由此可见,TreeSet底层实际使用的存储容器就是TreeMap。

与HashSet完全类似的是,TreeSet里绝大部分方法都是直接调用TreeMap的方法来实现的。

TreeSet实现原理及源码分析的更多相关文章

  1. OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

    http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...

  2. ConcurrentHashMap实现原理及源码分析

    ConcurrentHashMap实现原理 ConcurrentHashMap源码分析 总结 ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对Ha ...

  3. HashMap和ConcurrentHashMap实现原理及源码分析

    HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表, ...

  4. (转)ReentrantLock实现原理及源码分析

    背景:ReetrantLock底层是基于AQS实现的(CAS+CHL),有公平和非公平两种区别. 这种底层机制,很有必要通过跟踪源码来进行分析. 参考 ReentrantLock实现原理及源码分析 源 ...

  5. 【转】HashMap实现原理及源码分析

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景极其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...

  6. 【OpenCV】SIFT原理与源码分析:DoG尺度空间构造

    原文地址:http://blog.csdn.net/xiaowei_cqu/article/details/8067881 尺度空间理论   自然界中的物体随着观测尺度不同有不同的表现形态.例如我们形 ...

  7. 《深入探索Netty原理及源码分析》文集小结

    <深入探索Netty原理及源码分析>文集小结 https://www.jianshu.com/p/239a196152de

  8. HashMap实现原理及源码分析之JDK8

    继续上回HashMap的学习 HashMap实现原理及源码分析之JDK7 转载 Java8源码-HashMap  基于JDK8的HashMap源码解析  [jdk1.8]HashMap源码分析 一.H ...

  9. 【OpenCV】SIFT原理与源码分析:关键点描述

    <SIFT原理与源码分析>系列文章索引:http://www.cnblogs.com/tianyalu/p/5467813.html 由前一篇<方向赋值>,为找到的关键点即SI ...

随机推荐

  1. BeanFactory与ApplicationContext

    本文总结自:https://www.cnblogs.com/xiaoxi/p/5846416.html 我们常说的Spring容器(即Spring Ioc 容器),是如何创建bean的? BeanFa ...

  2. 20145215刘俊谦实验五 Java网络编程及安全

    实验内容 掌握Socket程序的编写: 掌握密码技术的使用: 设计安全传输系统. 实验步骤 本次实验由两人组队完成,20145321曾子誉是我本次实验的搭档,链接为:http://www.cnblog ...

  3. 20145215《Java程序设计》第二周学习总结

    教材内容总结 类型.变量与运算符 *基本类型 整数(short.int.long) 字节(byte) 浮点数(float/double) 字符(char)将一个数字字母或者符号用单引号标识,字符串用双 ...

  4. Java Swing简单的加法器

    package test; import java.awt.*; import javax.swing.*; import java.awt.event.*; public class FrameDe ...

  5. Mysql 默认编码问题

    新安装的数据库默认编码是 latin1 +--------------------------+----------------------------+ | Variable_name | Valu ...

  6. JavaScript的this指针到底指向哪?

    编程过程中,着实十分困扰this的指向性,经过查阅一番资料,终于搞清楚了,在这里总结一下,全文分为以下三个部分: 什么是this指针? this指针指向哪里? 何时使用this? 一 什么是this指 ...

  7. 自学Java测试代码二String, StringBuffer

    2017-08-23 10:38:01 writer:pprp package test; import java.util.*; public class test2 { public static ...

  8. 使用iview--1

    在任意一个你想创建项目的路径下 每次输入就输一致的就可以 /*************************安装选项开始****************/ 回车再次回车就如下,输入Y 继续 回车,输 ...

  9. Apache的MaxClients设置

    本文将介绍Apache的MaxClients参数的重要性以及在GC发生时对系统整体性能的显著影响.通过几个例子,你将会更清晰的理解MaxClients值所引发的问题.最后会介绍如何依据系统的可用内存来 ...

  10. Error:Cannot access first() element from an empty List

    解决方案: bintray版本问题,修改为: classpath 'com.novoda:bintray-release:0.3.4' 如下: buildscript { repositories { ...