Java集合框架之TreeSet
简述
TreeSet是基于TreeMap作为存储的可排序、可去重的有序集合
继承于AbstractSet,AbstractSet实现了equals和hashcode方法
实现了NavigableSet接口,意味着它支持一系列的导航方法,比如查找与指定目标最匹配项
实现了Cloneable接口,意味着它能被复制
实现了java.io.Serializable接口,意味着它支持序列化

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;
}
/**
* 以自然排序方式创建一个新的 TreeMap,
* 使用该 TreeMap 的 key 来保存 Set 集合的元素
*/
public TreeSet() {
this(new TreeMap<E,Object>());
}
/**
* 根据自定义排序方式创建一个新的 TreeMap,
* 使用该 TreeMap 的 key 来保存 Set 集合的元素
*/
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
/**
* 根据无参构造器创建一个 TreeSet,底层以 TreeMap 保存集合元素
* 向 TreeSet 中添加 指定Collection 集合 c 里的所有元素
*/
public TreeSet(Collection<? extends E> c) {
this();
addAll(c);
}
/**
* 根据有参构造器创建一个 TreeSet,底层以 TreeMap 保存集合元素
* 向 TreeSet 中添加 指定Collection 集合 c 里的所有元素
*/
public TreeSet(SortedSet<E> s) {
this(s.comparator());
addAll(s);
}
---------------下面来看addAll方法-------------------
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) {
# 把指定集合强制转换为 SortedSet 集合
SortedSet<? extends E> set = (SortedSet<? extends E>) c;
# 把NavigableMap集合强制转换为 TreeMap集合
TreeMap<E,Object> map = (TreeMap<E, Object>) m;
Comparator<?> cc = 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;
}
}
return super.addAll(c);
}
}
从上面代码可以看出,TreeSet 的前两个构造器的都是新建一个 TreeMap 作为实际存储 Set 元素的容器,而另外 2 个构造器则分别依赖于前两个构造器,由此可见,TreeSet 底层实际使用的存储容器就是 TreeMap
TreeSet排序方式
由源码我们可知TreeSet的排序方式有两种:
一是自然排序,使用默认构造函数
Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现该接口的类必须实现该方法,实现了该接口的类的对象就可以比较大小了。当一个对象调用该方法与另一个对象进行比较,
例如 obj1.compareTo(obj2)
如果该方法返回0,则表明这两个对象相等;
如果该方法返回一个正整数,则表明obj1大于obj2;
- 如果该方法返回一个负整数,则表明obj1小于obj2。
Java的一些常用类已经实现了Comparable接口,并提供了比较大小的标准, 下面是实现了Comparable接口的常用类:
BigDecimal、BigInteger以及所有数值型对应包装类:按它们对象的数值大小进行比较
Character :按字符的Unicode值进行比较
Boolean : true对应的包装类实例大于false对应的包装类实例
String : 按字符串中字符的Unicode值进行比较
Date、Time : 后面的时间、日期比前面的日期时间大。
二是比较器排序,使用指定比较器的构造函数
TreeSet的自然排序是根据集合元素的大小默认以升序排列。如果需要完成定制排序,例如以降序排列,则可以使用Comparator接口的帮助。
该接口里包含了一个int compare(T o1, T o2)方法,
该方法用于比较o1、o2的大小:
如果该方法返回正整数,则表明o1大于o2;
如果该方法返回0,则表明o1等于o2;
如果该方法返回负整数,则表明o1小于o2。
事例
以自然顺序排序,并且元素不重复
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<String> treeSet = new TreeSet<>();
for (int i = 0; i < 5; i++) {
treeSet.add("item" + i);
}
for (int i = 0; i < 5; i++) {
treeSet.add("item" + i);
}
treeSet.forEach(item -> {
System.err.println(item);
});
}
}
输出结果:
item0
item1
item2
item3
item4
按比较器排序
指定一个比较器,倒置集合中的元素
public class TreeSetDemo {
public static void main(String[] args) {
//指定一个比较器,倒置元素顺序
TreeSet<String> treeSet = new TreeSet<>(Comparator.reverseOrder());
for (int i = 0; i < 5; i++) {
treeSet.add("item" + i);
}
for (int i = 0; i < 5; i++) {
treeSet.add("item" + i);
}
treeSet.forEach(item -> {
System.err.println(item);
});
}
}
输出结果:
item4
item3
item2
item1
item0
HashSet和TreeSet区别
1)HashSet基于HashMap实现,HashSet里面的元素是无序的且不重复的
2)HashSet允许使用null,有且仅有一个元素为null
3)TreeSet基于TreeMap实现,是一个有序的集合
4)TreeSet中不允许使用null元素
5)TreeSet中的元素支持2种排序方式:自然排序 或者 根据 Comparator 进行排序
6)TreeSet不支持快速随机遍历,只能通过迭代器进行遍历!
7)HashSet和TreeSet都是非同步的,在使用Iterator进行迭代的时候要注意fail-fast
总结
TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储。
TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么该元素所属的类必须要实现Comparable接口,把元素的比较规则定义在compareTo(T o)方法上。如果比较元素的时候,compareTo方法返回 的是0,那么该元素就被视为重复元素,不允许添加
TreeSet添加元素的时候, 如果元素本身没有具备自然顺序 的特性,并且元素所属的类也没有实现Comparable接口,那么必须要在创建TreeSet的时候传入一个比较器。
TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,而元素所属的类已经实现了Comparable接口,在创建TreeSet对象的时候又传入了比较器,此时以比较器的比较规则优先使用。
Java集合框架之TreeSet的更多相关文章
- Java集合框架之TreeSet浅析
Java集合框架之TreeSet浅析 一.TreeSet综述: 1.1TreeSet简介: TreeSet是Java集合框架的重要成员,先来看看TreeSet在jdk1.8中的定义吧: public ...
- Java集合框架系列大纲
###Java集合框架之简述 Java集合框架之Collection Java集合框架之Iterator Java集合框架之HashSet Java集合框架之TreeSet Java集合框架之Link ...
- 【java集合框架源码剖析系列】java源码剖析之TreeSet
本博客将从源码的角度带领大家学习TreeSet相关的知识. 一TreeSet类的定义: public class TreeSet<E> extends AbstractSet<E&g ...
- Java集合框架List,Map,Set等全面介绍
Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I] +--java.util.ArrayList [C] +- ...
- Java 集合框架
Java集合框架大致可以分为五个部分:List列表,Set集合.Map映射.迭代器.工具类 List 接口通常表示一个列表(数组.队列.链表 栈),其中的元素 可以重复 的是:ArrayList 和L ...
- 【JAVA集合框架之Map】
一.概述.1.Map是一种接口,在JAVA集合框架中是以一种非常重要的集合.2.Map一次添加一对元素,所以又称为“双列集合”(Collection一次添加一个元素,所以又称为“单列集合”)3.Map ...
- 《深入理解Java集合框架》系列文章
Introduction 关于C++标准模板库(Standard Template Library, STL)的书籍和资料有很多,关于Java集合框架(Java Collections Framewo ...
- Java 集合系列 17 TreeSet
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- 【Java集合框架】规则集--Set
集合: Java主要支持三种: 1.规则集(Set) 用于存储一组不重复的元素 2.线性表(List) 用于存储一个由元素构成的有序集合 3.队列(Queue) 同与数据结构中的队列,存储用先进先出的 ...
随机推荐
- 怎样理解DOM
一句话总结: DOM 是一个 js 对象. 他可以赋予 js 控制 html 文档的能力. 全称: Document Object Model. DOM 的最小组成单位是: 节点 , 节点有7种类型 ...
- winform messageBox.Show()
MessageBox.Show(" 5 个参数...... ", " 亮仔提示", MessageBoxButtons.OKCancel, ...
- 三、maven学习-高级
maven父子工程
- java文件上传复制等功能
package com.sitech.message.controller.task;import java.io.File;//引入类 import java.io.FileInputStream; ...
- 如何将webstrom本地的代码上传到github上
首先注册一个github账户,然后下载一个git软件. 文件夹的任意处点击右键,找到gitbash here,打开终端命令窗口. 因为我们本地 Git 仓库和 GitHub 仓库之间的传输是通过 S ...
- jboss日志的自定义
最近由于想着每次调试socket接收数据情况都需要源码debug好麻烦,要是能把接收到的数据输出到一个单独的日志文件,那出问题的时候,查看问题就方便多了. log4j的日志是可以很方便自定义的,只是这 ...
- shell运行下的写日志
tee 重定向输出到多个文件 在执行Linux命令时,我们既想把输出保存到文件中,又想在屏幕上看到输出内容,就可以使用tee命令 要注意的是:在使用管道线时,前一个命令的标准错误输出不会被tee读 ...
- JavaJDBC【一、概述】
其实这个内容在学习java基础的时候就有看过了,只是没有详细整理,在这再整理一下 数据库操作对于任何一门后端语言来说都是很重要的 JDBC:Java Data Base Connectivity 内容 ...
- Element 封印
官方网站 https://element.eleme.cn/#/zh-CN 简介 Element 是一套为开发者.设计者和产品经理准备的基于Vue2.0的组件库,提供了配套的设计资源,帮助快速建立网站 ...
- odoo标识符
class Book(models.Model): _name = "library.book" _description = "Book" _order = ...