集合之TreeSet(含JDK1.8源码分析)
一、前言
前面分析了Set接口下的hashSet和linkedHashSet,下面接着来看treeSet,treeSet的底层实现是基于treeMap的。
四个关注点在treeSet上的答案
二、treeSet的数据结构
因为treeSet的底层是基于treeMap的,所以treeSet的数据结构就是treeMap的数据结构:红黑树,因为前面已经分析过了treeMap的数据结构,这里不再赘述。集合之TreeMap(含JDK1.8源码分析)。
三、treeSet源码分析-属性及构造函数
3.1 类的继承关系
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable
说明:实现了NavigableSet接口,定义了一些共有的操作。
3.2 类的属性
/**
* The backing map.
*/
private transient NavigableMap<E,Object> m; // Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object(); //版本号
private static final long serialVersionUID = -2479143000061671589L;
说明:属性m为NavigableMap接口,treeSet的一些操作都是基于此map的,而前面分析treeMap的时候,发现treeMap实现了NavigableMap接口,所以hashSet中基于NavigableMap接口的操作实际上都是基于其实现类treeMap的操作,此处也是多态的概念。
treeMap的继承实现关系:
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable
而对于Object类型的属性PRESENT,在分析hashSet的时候已经做了说明,因为map(treeSet中是NavigableMap)是存储key-value键值对的,所以PRESENT只是配一下key-value中value的位置,起个占位的作用,没有什么实际的意义,所有通过treeSet添加进来的key都对应同一个value值,PRESENT。
3.3 类的构造函数
1、TreeSet(NavigableMap<E,Object> m)型
/**
* Constructs a set backed by the specified navigable map.
*/
TreeSet(NavigableMap<E,Object> m) {
this.m = m;
}
说明:构建一个treeSet,基于navigable map(其实现类treeMap)实现的。
2、TreeSet()型
/**
* Constructs a new, empty tree set, sorted according to the
* natural ordering of its elements. All elements inserted into
* the set must implement the {@link Comparable} interface.
* Furthermore, all such elements must be <i>mutually
* comparable</i>: {@code e1.compareTo(e2)} must not throw a
* {@code ClassCastException} for any elements {@code e1} and
* {@code e2} in the set. If the user attempts to add an element
* to the set that violates this constraint (for example, the user
* attempts to add a string element to a set whose elements are
* integers), the {@code add} call will throw a
* {@code ClassCastException}.
*/
public TreeSet() {
this(new TreeMap<E,Object>());
}
说明:构建一个treeSet,排序是基于插入元素的自然顺序。
3、TreeSet(Comparator<? super E> comparator)型
/**
* Constructs a new, empty tree set, sorted according to the specified
* comparator. All elements inserted into the set must be <i>mutually
* comparable</i> by the specified comparator: {@code comparator.compare(e1,
* e2)} must not throw a {@code ClassCastException} for any elements
* {@code e1} and {@code e2} in the set. If the user attempts to add
* an element to the set that violates this constraint, the
* {@code add} call will throw a {@code ClassCastException}.
*
* @param comparator the comparator that will be used to order this set.
* If {@code null}, the {@linkplain Comparable natural
* ordering} of the elements will be used.
*/
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
说明:构建一个treeSet,排序是基于自定义的比较器的排序规则。
4、TreeSet(Collection<? extends E> c)型
/**
* Constructs a new tree set containing the elements in the specified
* collection, sorted according to the <i>natural ordering</i> of its
* elements. All elements inserted into the set must implement the
* {@link Comparable} interface. Furthermore, all such elements must be
* <i>mutually comparable</i>: {@code e1.compareTo(e2)} must not throw a
* {@code ClassCastException} for any elements {@code e1} and
* {@code e2} in the set.
*
* @param c collection whose elements will comprise the new set
* @throws ClassCastException if the elements in {@code c} are
* not {@link Comparable}, or are not mutually comparable
* @throws NullPointerException if the specified collection is null
*/
public TreeSet(Collection<? extends E> c) {
this();
addAll(c);
}
说明:构建一个treeSet,包含参数c中的元素,排序是基于元素的自然顺序。
5、TreeSet(SortedSet<E> s)型
/**
* Constructs a new tree set containing the same elements and
* using the same ordering as the specified sorted set.
*
* @param s sorted set whose elements will comprise the new set
* @throws NullPointerException if the specified sorted set is null
*/
public TreeSet(SortedSet<E> s) {
this(s.comparator());
addAll(s);
}
说明:构建一个treeSet,排序是基于SortedSet指定的排序规则。
四、treeSet源码分析-核心函数
4.1 增:add函数----存储元素
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element {@code e} to this set if
* the set contains no element {@code e2} such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns {@code false}.
*
* @param e element to be added to this set
* @return {@code true} if this set did not already contain the specified
* element
* @throws ClassCastException if the specified object cannot be compared
* with the elements currently in this set
* @throws NullPointerException if the specified element is null
* and this set uses natural ordering, or its comparator
* does not permit null elements
*/
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
说明:添加一个原先set中未存在的元素,返回true,若是该元素已经存在,set不做改变,返回false。
可以看到其方法内部调用navigableMap的put方法,因为treeMap是其实现类,所以实际执行的时候,调用的是treeMap的put方法。可参见:集合之TreeMap(含JDK1.8源码分析)。
4.2 增:remove函数----删除元素
/**
* Removes the specified element from this set if it is present.
* More formally, removes an element {@code e} such that
* <tt>(o==null ? e==null : o.equals(e))</tt>,
* if this set contains such an element. Returns {@code true} if
* this set contained the element (or equivalently, if this set
* changed as a result of the call). (This set will not contain the
* element once the call returns.)
*
* @param o object to be removed from this set, if present
* @return {@code true} if this set contained the specified element
* @throws ClassCastException if the specified object cannot be compared
* with the elements currently in this set
* @throws NullPointerException if the specified element is null
* and this set uses natural ordering, or its comparator
* does not permit null elements
*/
public boolean remove(Object o) {
return m.remove(o)==PRESENT;
}
说明:若set中存在要删除的元素,删除,返回true,不存在,返回false。
可以看到其方法内部调用navigableMap的remove方法,因为treeMap是其实现类,所以实际执行的时候,调用的是treeMap的remove方法。可参见:集合之TreeMap(含JDK1.8源码分析)。
4.3 contains函数----是否存在该元素
/**
* Returns {@code true} if this set contains the specified element.
* More formally, returns {@code true} if and only if this set
* contains an element {@code e} such that
* <tt>(o==null ? e==null : o.equals(e))</tt>.
*
* @param o object to be checked for containment in this set
* @return {@code true} if this set contains the specified element
* @throws ClassCastException if the specified object cannot be compared
* with the elements currently in the set
* @throws NullPointerException if the specified element is null
* and this set uses natural ordering, or its comparator
* does not permit null elements
*/
public boolean contains(Object o) {
return m.containsKey(o);
}
说明:若set中存在该元素,返回true,不存在,返回false。
可以看到其方法内部调用navigableMap的containsKey方法,因为treeMap是其实现类,所以实际执行的时候,调用的是treeMap的containsKey方法。
五、总结
总之,treeSet底层是基于treeMap实现的,可以自定义比较器对元素进行排序,或是使用元素的自然顺序。
集合之TreeSet(含JDK1.8源码分析)的更多相关文章
- 集合之LinkedHashSet(含JDK1.8源码分析)
一.前言 上篇已经分析了Set接口下HashSet,我们发现其操作都是基于hashMap的,接下来看LinkedHashSet,其底层实现都是基于linkedHashMap的. 二.linkedHas ...
- 集合之HashSet(含JDK1.8源码分析)
一.前言 我们已经分析了List接口下的ArrayList和LinkedList,以及Map接口下的HashMap.LinkedHashMap.TreeMap,接下来看的是Set接口下HashSet和 ...
- 集合之HashMap(含JDK1.8源码分析)
一.前言 之前的List,讲了ArrayList.LinkedList,反映的是两种思想: (1)ArrayList以数组形式实现,顺序插入.查找快,插入.删除较慢 (2)LinkedList以链表形 ...
- 集合之LinkedList(含JDK1.8源码分析)
一.前言 LinkedList是基于链表实现的,所以先讲解一下什么是链表.链表原先是C/C++的概念,是一种线性的存储结构,意思是将要存储的数据存在一个存储单元里面,这个存储单元里面除了存放有待存储的 ...
- 集合之ArrayList(含JDK1.8源码分析)
一.ArrayList的数据结构 ArrayList底层的数据结构就是数组,数组元素类型为Object类型,即可以存放所有类型数据.我们对ArrayList类的实例的所有的操作(增删改查等),其底层都 ...
- 集合之TreeMap(含JDK1.8源码分析)
一.前言 前面所说的hashMap和linkedHashMap都不具备统计的功能,或者说它们的统计性能的时间复杂度都不是很好,要想对两者进行统计,需要遍历所有的entry,时间复杂度比较高,此时,我们 ...
- 集合之LinkedHashMap(含JDK1.8源码分析)
一.前言 大多数的情况下,只要不涉及线程安全问题,map都可以使用hashMap,不过hashMap有一个问题,hashMap的迭代顺序不是hashMap的存储顺序,即hashMap中的元素是无序的. ...
- 【集合框架】JDK1.8源码分析之HashMap(一) 转载
[集合框架]JDK1.8源码分析之HashMap(一) 一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化 ...
- 【集合框架】JDK1.8源码分析之ArrayList详解(一)
[集合框架]JDK1.8源码分析之ArrayList详解(一) 一. 从ArrayList字表面推测 ArrayList类的命名是由Array和List单词组合而成,Array的中文意思是数组,Lis ...
随机推荐
- 转://Oracle中定义者权限和调用者权限案例分析
定义者权限:定义者权限指使用它所有者的权限,而不是当前用户来执行过程.因此,你可以限制用户执行的数据库操作,允许他们仅通过运行定义者权限的过程和函数访问数据.创建过程.函数和程序包的默认权限是定义者权 ...
- Linux:Day8(上) 文件系统挂载和管理工具
文件系统管理: 将额外文件系统与根文件系统某现存的目录建立起关联关系,进而使得此目录做为其它文件访问入口的行为称之为挂载: 解除此关联关系的过程称之为卸载: 把设备关联挂载点:Mount Point ...
- nginx之七:nginx path(root)文件路径配置
nginx指定文件路径有两种方式root和alias,这两者的用法区别,使用方法总结了如下,方便大家在应用过程中,快速响应.root和alias主要区别在于如何解释location后面的uri,这会使 ...
- Emacs 自动补全插件 ycmd
Emacs 自动补全,最好的插件当属 ycmd.以下记录我的安装过程. 1. 安装 ycmd server github 官方地址: https://github.com/Valloric/ycmd ...
- 红米Note5进入全网通5.0时代,其实是高通已经落后了!
高通早在去年12月份就正式发布了新一代的骁龙845处理器,接下来就是人们对于搭载骁龙845处理器的手机充满期待,可是转眼到了2018年的3月份,目前已经发布的高端旗舰新机却只有三星S9和三星S9+,而 ...
- git branch 分支操作
一.git分支命令 Git鼓励大量使用分支: 查看分支:git branch 创建分支:git branch <name> 切换分支:git checkout <name> 创 ...
- ASP MD5
<% Private Const BITS_TO_A_BYTE = 8 Private Const BYTES_TO_A_WORD = 4 Private Const BITS_TO_A_WOR ...
- Java消息中间件入门笔记 - ActiveMQ篇
入门 消息中间件带来的好处: 1)解耦:系统解耦 2)异步:异步执行 3)横向扩展 4)安全可靠 5)顺序保证 栗子: 通过服务调用让其它系统感知事件发生 系统之间高耦合 程序执行效率低 通过消息中间 ...
- Python股票分析系列——获得标普500的所有公司股票数据.p6
该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第6部分. 在之前的Python教程中,我们介绍了如何获取我们感兴趣的公司名单(在我们的案例中是 ...
- 朱晔的互联网架构实践心得S2E3:品味Kubernetes的设计理念
Kubernetes(k8s)是一款开源的优秀的容器编排调度系统,其本身也是一款分布式应用程序.虽然本系列文章讨论的是互联网架构,但是k8s的一些设计理念非常值得深思和借鉴,本人并非运维专家,本文尝试 ...