Java集合(6):TreeSet
一.TreeSet介绍
与HashSet是基于HashMap实现一样,TreeSet是基于TreeMap实现的。TreeSet是一个有序集合,TreeSet中的元素将按照升序排列,缺省是按照自然排序进行排列,Integer能排序(有默认顺序), String能排序(有默认顺序), 如果想把自定义类的对象存入TreeSet进行排序, 那么必须实现Comparable接口。或者有一个自定义的比较器。我们可以在构造TreeSet对象时,传递实现Comparator接口的比较器对象。
1.TreeSet的继承关系
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable
2.TreeSet的类图关系如下:

通过源码我们知道TreeSet继承自AbstractSet,实现了NavigableSet、Cloneable、Serializable接口。其中AbstractSet提供 Set 接口的骨干实现,从而最大限度地减少了实现此接口所需的工作。NavigableSet是扩展的 SortedSet,具有了为给定搜索目标报告最接近匹配项的导航方法,这就意味着它支持一系列的导航方法。比如查找与指定目标最匹配项。Cloneable支持克隆,Serializable支持序列化。
二.TreeSet源码解析
1.私有属性
private transient NavigableMap<E,Object> m; //PRESENT会被当做Map的value与key构建成键值对
private static final Object PRESENT = new Object();
2.TreeSet的构造方法
//默认构造方法,根据其元素的自然顺序进行排序
public TreeSet() {
this(new TreeMap<E,Object>());
} //构造一个包含指定 collection 元素的新 TreeSet,它按照其元素的自然顺序进行排序。
public TreeSet(Collection<? extends E> c) {
this();
addAll(c);
} //构造一个新的空 TreeSet,它根据指定比较器进行排序。
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
} //构造一个与指定有序 set 具有相同映射关系和相同排序的新 TreeSet。
public TreeSet(SortedSet<E> s) {
this(s.comparator());
addAll(s);
} TreeSet(NavigableMap<E,Object> m) {
this.m = m;
}
3.其他方法
3.1 add
public boolean add(E e)
将指定的元素添加到此 set(如果该元素尚未存在于 set 中)。
3.2 addAll
public boolean addAll(Collection<? extends E> c)
将指定 collection 中的所有元素添加到此 set 中。
3.3 remove
public boolean remove(Object o)
将指定的元素从 set 中移除(如果该元素存在于此 set 中)。
3.4 clear
public void clear()
移除此 set 中的所有元素。
3.5 clone
public Object clone()
返回 TreeSet 实例的浅表副本。属于浅拷贝。
3.6 size
public int size()
返回 set 中的元素数(set 的容量)。
3.7 isEmpty
public boolean isEmpty()
如果此 set 不包含任何元素,则返回 true。
3.8 comparator
public Comparator<? super E> comparator()
返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null。
3.9 contains
public boolean contains(Object o)
如果此 set 包含指定的元素,则返回 true。
3.10 iterator
public Iterator<E> iterator()
返回在此 set 中的元素上按升序进行迭代的迭代器。
3.11 first
public E first()
返回此 set 中当前第一个(最低)元素。
3.12 last
public E last()
返回此 set 中当前最后一个(最高)元素。
3.13 higher
public E higher(E e)
返回此 set 中严格大于给定元素的最小元素;如果不存在这样的元素,则返回 null。
3.14 lower
public E lower(E e)
返回此 set 中严格小于给定元素的最大元素;如果不存在这样的元素,则返回 null。
3.15 ceiling
public E ceiling(E e)
返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null。
3.16 floor
public E floor(E e)
返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null。
还有一些其他的方法,太多了,这里就不写了,都快写成中文API了,上面这些都是些较为常用的方法,其他的方法用到的时候查下源码吧。
三.TreeSet使用示例
1.String 类的排序
public class TreeSetTest {
public static void main(String[] args) {
Set ts = new TreeSet();
ts.add("abc");
ts.add("xyz");
ts.add("rst");
Iterator it = ts.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
输出结果:
abc
rst
xyz
打印结果不是和先前加入的顺序一样,它是按照一个字母的排序法进行排序的。这是因为String 类实现了Comparable接口。
2.自定义类的排序
如果我们自己定义的一个类的对象要加入到TreeSet当中,那么这个类必须要实现Comparable接口。
public class test_treeset {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Set ts = new TreeSet();
ts.add(new Teacher("zhangsan", 1));
ts.add(new Teacher("lisi", 2));
ts.add(new Teacher("wangmazi", 3));
ts.add(new Teacher("wangwu",4));
ts.add(new Teacher("mazi", 3));
Iterator it = ts.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
class Teacher implements Comparable {
int num;
String name;
Teacher(String name, int num) {
this.num = num;
this.name = name;
}
public String toString() {
return "学号:" + num + "\t\t姓名:" + name;
}
//o中存放时的红黑二叉树中的节点,从根节点开始比较
public int compareTo(Object o) {
Teacher ss = (Teacher) o;
int result = num < ss.num ? 1 : (num == ss.num ? 0 : -1);//降序
//int result = num > ss.num ? 1 : (num == ss.num ? 0 : -1);//升序
if (result == 0) {
result = name.compareTo(ss.name);
}
return result;
}
}
运行结果:
学号:4 姓名:wangwu
学号:3 姓名:mazi
学号:3 姓名:wangmazi
学号:2 姓名:lisi
学号:1 姓名:zhangsan
注意:如果将int result = num > ss.num ? 1 : (num == ss.num ? 0 : -1);写成了int result = ss.num > num ? 1 : (ss.num == num ? 0 : -1);那么得到的结果就是倒序排列的,并不是升序的。
3.比较器
在使用TreeSet对加入到其中的元素进行排序的时候可以像Arrays对数组中的元素进行排序和Collections对集合中的元素进行排序一样,传递一个比较器。
构造一个新的空TreeSet,它根据指定比较器进行排序。插入到该 set 的所有元素都必须能够由指定比较器进行相互比较:对于 set 中的任意两个元素 e1 和e2,执行 comparator.compare(e1, e2) 都不得抛出 ClassCastException。如果用户试图将违反此约束的元素添加到 set 中,则 add 调用将抛出 ClassCastException。
class Teacher {
int num;
String name;
Teacher(String name, int num) {
this.num = num;
this.name = name;
}
public String toString() {
return "学号:" + num + " 姓名:" + name;
}
static class TeacherCompare implements Comparator {// 老师自带的一个比较器
public int compare(Object o1, Object o2) {
Teacher s1 = (Teacher) o1;// 转型
Teacher s2 = (Teacher) o2;// 转型
int result = s1.num > s2.num ? 1 : (s1.num == s2.num ? 0 : -1);
if (result == 0) {
result = s1.name.compareTo(s2.name);
}
return result;
}
}
}
运行结果:
学号:1 姓名:lisi
学号:2 姓名:zhangsan
学号:3 姓名:mazi
学号:3 姓名:wangmazi
参考:http://cmsblogs.com/?p=1162
http://www.cnblogs.com/meng72ndsc/archive/2010/12/23/1914477.html
Java集合(6):TreeSet的更多相关文章
- Java集合之TreeSet
TreeSet是一个有序的集合,它的作用是提供有序的Set集合.它继承了AbstractSet抽象类,实现了NavigableSet<E>,Cloneable,Serializable接口 ...
- java 集合框架(TreeSet操作,自动对数据进行排序,重写CompareTo方法)
/*TreeSet * treeSet存入数据后自动调用元素的compareTo(Object obj) 方法,自动对数据进行排序 * 所以输出的数据是经过排序的数据 * 注:compareTo方法返 ...
- 死磕 java集合之TreeSet源码分析
问题 (1)TreeSet真的是使用TreeMap来存储元素的吗? (2)TreeSet是有序的吗? (3)TreeSet和LinkedHashSet有何不同? 简介 TreeSet底层是采用Tree ...
- 死磕 java集合之终结篇
概览 我们先来看一看java中所有集合的类关系图. 这里面的类太多了,请放大看,如果放大还看不清,请再放大看,如果还是看不清,请放弃. 我们下面主要分成五个部分来逐个击破. List List中的元素 ...
- Java 集合系列17之 TreeSet详细介绍(源码解析)和使用示例
概要 这一章,我们对TreeSet进行学习.我们先对TreeSet有个整体认识,然后再学习它的源码,最后再通过实例来学会使用TreeSet.内容包括:第1部分 TreeSet介绍第2部分 TreeSe ...
- Java 集合系列 17 TreeSet
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- Java基础知识强化之集合框架笔记47:Set集合之TreeSet保证元素唯一性和比较器排序的原理及代码实现(比较器排序:Comparator)
1. 比较器排序(定制排序) 前面我们说到的TreeSet的自然排序是根据集合元素的大小,TreeSet将它们以升序排列. 但是如果需要实现定制排序,比如实现降序排序,则要通过比较器排序(定制排序)实 ...
- Java基础知识强化之集合框架笔记46:Set集合之TreeSet存储自定义对象并遍历练习2(自然排序:Comparable)
1. TreeSet存储自定义对象并遍历练习2: (1)Student.java package cn.itcast_06; /* * 如果一个类的元素要想能够进行自然排序,就必须实现自然排序接口 * ...
- Java基础知识强化之集合框架笔记45:Set集合之TreeSet存储自定义对象并遍历练习1(自然排序:Comparable)
1. 自然排序: TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后将集合元素按照升序排列,这种方式就是自然排序. Java中提供了一个Comp ...
- Java集合概述、Set集合(HashSet类、LinkedHashSet类、TreeSet类、EnumSet类)
Java集合概述.Set集合(HashSet类.LinkedHashSet类.TreeSet类.EnumSet类) 1.Java集合概述1)数组可以保存多个对象,但数组长度不可变,一旦在初始化数组时指 ...
随机推荐
- 基于nc实现聊天
需要 Netcat(在网络上通过 TCP 或 UDP 读写数据),CentOS 6.x 系统中默认没有安装,经过测试,如果通过 yum 直接安装,运行时会有 “nc: Protocol not ava ...
- C# Dictionary学习
http://www.cnblogs.com/gdjlc/archive/2010/01/22/2086922.html http://wenku.baidu.com/link?url=TOgeedl ...
- windows server 服务器添加免费域名证书的方法(Let's Encrypt)
在 windows server 服务器上可以通过 win-acme工具添加ssl 1.首先下载工具 https://github.com/PKISharp/win-acme/releases 最新版 ...
- 自己动手写ORM(02):Sql生成器实现
上一节中鄙人通过解析表达式树生成Sql碎片,其中我也把解析表达式类代码贴了出来,文章发布之后我对ExpressionAnalyzer类做了些改动,下面我还会将代码贴出来,废话不多说,直接进入今天的主题 ...
- 配置管理之PackageProvider接口
PackageProvider的开始 从前面几章中我们了解到了一点:想知道如何加载相关配置文件就必须去找StrutsXmlConfigurationProvider类和XmlConfiguratio ...
- 应用IBatisNet+Castle进行项目的开发
最近在做一个项目,项目的需求不够明确,这是做项目的大忌,但是没有办法.项目的架构采用Dotnet平台使用C#进行开发,为了加快项目的开发进度,采用代码生成工具之MyGeneration 生成业务基本代 ...
- 【BZOJ4385】[POI2015]Wilcze doły 单调栈+双指针法
[BZOJ4385][POI2015]Wilcze doły Description 给定一个长度为n的序列,你有一次机会选中一段连续的长度不超过d的区间,将里面所有数字全部修改为0.请找到最长的一段 ...
- 170221、浅谈mysql的SQL的四种连接
例子: ------------------------------------------------- a表 id name b表 id job pare ...
- iis express worker process已停止工作
以管理员方式运行命令提示符工具,然后执行以下语句 netsh winsock reset 重启电脑
- 容器OOM相关
使用容器的时候经常出现容器无缘无故重启的情况,首先我们要怀疑的应该是是否发生OOM了,通过以下命令可以查看 需要在容器的宿主机上在执行,宿主机上执行/var/log/dmesg有相关信息 dmesg ...