TreeSet是一个有序集,它的作用是提供一个有序集集合。本文主要介绍TreeSet的使用实例,有一定的参考价值,感兴趣的朋友可以参考一下。
第1部分 TreeSet介绍
TreeSet简介
TreeSet是一个有序集,它的作用是提供一个有序集集合。它从AbstractSet类继承,并实现可导航的Set、Cloneable、java.io.serializable接口。
TreeSet继承自AbstractSet,所以它是一个集合集合,具有Set的属性和方法。
TreeSet实现了NavigableSet接口,这意味着它支持一系列导航方法。例如找到与指定目标的最佳匹配。
TreeSet实现了Cloneable接口,这意味着它可以被克隆。
TreeSet实现了java.io.Serializable接口,这意味着它支持序列化。
TreeSet基于TreeMap实现。TreeSet中的元素支持两种排序方法:自然排序或根据创建TreeSet时提供的比较器排序。这取决于所用的施工方法。
TreeSet为基本操作(添加、删除和包含)提供了有保证的log(n)时间开销。
另外,TreeSet是异步的。迭代器方法返回的迭代器是快速失败的。
TreeSet的构造函数
//默认构造函数。使用这个构造函数,TreeSet中的元素以自然顺序排列。
树集()
//创建的树集包含集合
TreeSet(收藏?扩展E系列)
//指定TreeSet的比较器
TreeSet(比较器?超级E比较仪)
//创建的TreeSet包含Set。
树集(排序集)
TreeSet的API
布尔加法(E对象)
布尔型addAll(集合?扩展E系列)
空清除()
对象克隆()
布尔包含(对象对象)
e优先()
布尔型isEmpty()
E last()
民意优先
波尔拉斯特
东下(东)
东楼
E天花板
E更高(东)
布尔删除(对象对象)
int size()
比较器?超级E比较仪()
迭代器迭代器()
迭代器下降迭代器()
分类耳机(E端)
可导航集descendingSet()
可导航耳机(E端,布尔端不含)
排序子集(E开始,E结束)
可导航子集(E开始,布尔开始包含,E结束,布尔结束包含)
可导航集tailSet(E start,boolean startInclusive)
分类排序尾组(E开始)
说明:
(01) TreeSet是有序集集合,所以支持add、remove、get等方法。
(02)和NavigableSet一样,TreeSet的导航方式大致可以分为两类。一类提供元素项的导航方法,返回一个元素;另一类提供集合的导航方法,返回某个集合。
下限、下限、上限和上限分别返回小于、小于或等于、大于或等于和大于给定元素的元素,如果不存在这样的元素,则返回null。
第2部分 TreeSet数据结构
TreeSet的继承关系
java.lang.Object
公共类TreeSetE扩展AbstractSetE
实现NavigableSetE、Cloneable、java.io.Serializable{}
树集和集合之间的关系如下:
从图中可以看出:
(01) TreeSet继承AbstractSet,实现NavigableSet接口。
(02)TreeSet的本质是一个‘有序且无重复元素’的集合,通过TreeMap来实现。TreeSet包含一个“NavigableMap”类型的成员变量“M”,M实际上是“TreeMap”的一个实例。
第3部分 TreeSet源码解析(基于JDK1.6.0_45)
为了更好的了解TreeSet的原理,下面是对TreeSet源代码的分析。
包java.util
公共类TreeSetE扩展AbstractSetE
实现NavigableSetE、Cloneable、java.io.Serializable
{
//NavigableMap对象
私有瞬态NavigableMapE,Object m;
//TreeSet通过TreeMap实现,
//PRESENT是键值对中的值。
私有静态最终对象PRESENT=new Object();
//没有参数的构造函数。创建一个空的树形图。
公共树集(){
this(new TreeMapE,Object());
}
//将树形图赋值给导航地图对象' m '
TreeSet(导航mape,对象m) {
this.m=m
}
//带比较器的构造函数。
公共树集(比较器?超级比较器){
this(new TreeMapE,Object(comparator));
}
//创建树集,并将集合c中的全部元素都添加到树集中
公共树集(集合?扩展中文){
this();
//将集合c中的元素全部添加到树集中
addAll(c);
}
//创建树集,并将s中的全部元素都添加到树集中
公共树集(已排序集){
this(s .比较器());
addAll(s);
}
//返回树集的顺序排列的迭代器。
//因为树集时树形图实现的,所以这里实际上时返回树形图的"键集"对应的迭代器
公共迭代器迭代器(){
返回m.navigableKeySet().迭代器();
}
//返回树集的逆序排列的迭代器。
//因为树集时树形图实现的,所以这里实际上时返回树形图的"键集"对应的迭代器
公共迭代器descendingIterator() {
返回m.descendingKeySet().迭代器();
}
//返回树集的大小
public int size() {
返回m . size();
}
//返回树集是否为空
public boolean isEmpty() {
返回m . isempty();
}
//返回树集是否包含对象(o)
公共布尔包含(对象o) {
返回m .包含键(o);
}
//添加e到树集中
公共布尔加法(E e) {
return m.put(e,PRESENT)==null;
}
//删除树集中的对象o
公共布尔移除(对象o) {
return m . remove(o)==PRESENT;
}
//清空树集
公共void clear() {
m。clear();
}
//将集合c中的全部元素添加到树集中
公共布尔addAll(集合?扩展中文){
//如果适用,使用线性时间版本
if (m.size()==0 c.size() 0
c已排序集合的实例
树形图的m个实例){
SortedSet?扩展E集=(SortedSet?延伸e)c;
TreeMapE,Object map=(TreeMapE,Object)m;
比较器?超电子抄送=(比较器?超级E)集。比较器();
比较器?超级E MC=地图。比较器();
if (cc==mc || (cc!=null cc.equals(mc))) {
map.addAllForTreeSet(set,PRESENT);
返回真实的
}
}
返回超级棒。addall(c);
}
//返回子设置,实际上是通过树形图的子地图()实现的。
公共可导航子集(E fromElement,boolean fromInclusive,
E toElement,boolean toInclusive) {
返回新的TreeSetE(m.subMap(fromElement,fromInclusive,
toElement,to inclusive));
}
//返回一组的头部,范围是:从头部到toElement。
//包含是是否包含到元素的标志
公共导航耳机(E toElement,布尔值包含){
返回新的TreeSetE(m.headMap(toElement,含));
}
//返回一组的尾部,范围是:从从元素到结尾。
//包含是是否包含从元素的标志
公共可导航集尾集(E fromElement,布尔型包含){
返回新的TreeSetE(m.tailMap(fromElement,含));
}
//返回子设置。范围是:从来自元素(包括)到toElement(不包括)。
公共排序子集(E fromElement,E toElement) {
返回子集(fromElement,true,toElement,false);
}
//返回一组的头部,范围是:从头部到toElement(不包括)。
公共分类耳机(E toElement) {
返回耳机(toElement,false);
}
//返回一组的尾部,范围是:从从元素到结尾(不包括)。
公共排序集尾集(E来自元素){
返回tailSet(fromElement,true);
}
//返回一组的比较器
公共比较器?超级比较器(){
返回m . comparator();
}
//返回一组的第一个元素
公共E优先(){
返回m . first key();
}
//返回一组的最后一个元素
公共E优先(){
public E last() {
返回m . last key();
}
//返回一组中小于e的最大元素
公共E下(E东){
返回m .下键(e);
}
//返回一组中小于/等于e的最大元素
公共E层(东E层){
返回m .楼层钥匙(e);
}
//返回一组中大于/等于e的最小元素
公共E天花板(英英)
返回m .天花板钥匙(e);
}
//返回一组中大于e的最小元素
公立高等教育
返回m .较高的调(e);
}
//获取第一个元素,并将该元素从树形图中删除。
public E pollFirst() {
地图EntryE?e=m . pollfirstentry();
return (e==null)?null:e . getkey();
}
//获取最后一个元素,并将该元素从树形图中删除。
public E pollLast() {
地图EntryE?e=m . pollastentry();
return (e==null)?null:e . getkey();
}
//克隆一个树集,并返回目标对象
公共对象克隆(){
TreeSetE克隆=空
尝试{
clone=(TreeSetE)super。clone();
} catch(CloneNotSupportedException e){
抛出新的内部错误();
}
clone.m=new TreeMapE,Object(m);
返回克隆;
}
//java.io.Serializable的写入函数
//将树集的"比较器、容量,所有的元素值"都写入到输出流中
私有void writeObject(Java。io。对象输出流
抛出java.io.IOException {
s。defaultwriteobject();
//写入比较器
s。writeobject(m . comparator());
//写入容量
s。write int(m . size());
//写入"树集中的每一个元素"
对于(迭代器i=m.keySet().迭代器();I .有next();)
s。writeobject(I . next());
}
//java.io.Serializable的读取函数:根据写入方式读出
//先将树集的"比较器、容量、所有的元素值"依次读出
私有void读取对象(Java。io。对象输入流
抛出java.io.IOException,ClassNotFoundException {
//读入任何隐藏的东西
s。默认读取对象();
//从输入流中读取树集的"比较器"
比较器?超英中=(比较器?超级E)s . read object();
TreeMapE,对象tm
if (c==null)
tm=new TreeMapE,Object();
其他
tm=new TreeMapE,Object(c);
m=tm
//从输入流中读取树集的"容量"
int size=s . readint();
//从输入流中读取树集的"全部元素"
tm.readTreeSet(大小,s,当前);
}
//TreeSet的序列版本号
private static final long serialVersionUID=-2479143000061671589 l;
}
总结:
(01)树集实际上是树形图实现的。当我们构造树集时;若使用不带参数的构造函数,则树集的使用自然比较器;若用户需要使用自定义的比较器,则需要使用带比较器的参数。
(02)树集是非线程安全的。
(03)树集实现java.io。序列化的方式。当写入到输出流时,依次写入"比较器、容量、全部元素";当读出输入流时,再依次读取。
第4部分 TreeSet遍历方式
4.1迭代器顺序遍历
for(迭代器ITER=集。迭代器();ITER。有next();) {
ITER。next();
}
4.2迭代器顺序遍历
//假设设置是树集对象
for(迭代器ITER=集。降序迭代器();ITER。有next();) {
ITER。next();
}
每个人4.3英镑遍历哈希特
//假设设置是树集对象,并且设置中元素是线类型
String[]arr=(String[])集。to数组(新字符串[0]);
对于(字符串字符串:arr)
系统。出去。printf(' for each:% s \ n ',str);
树集不支持快速随机遍历,只能通过迭代器进行遍历!
树集遍历测试程序如下:
导入Java。util。*;
/**
* @desc树集的遍历程序
*
* @作者天行
* @电子邮件kuiwu-wang@163.com
*/
公共类TreeSetIteratorTest {
公共静态void main(String[] args) {
TreeSet set=new TreeSet();
设置。add(' AAA ');
设置。add(' AAA ');
设置。add(' BBB ');
设置。add(“eee”);
设置。添加(' DDD ');
设置。添加(“CCC”);
//顺序遍历树集
asciiterthrouveiterator(集);
//逆序遍历树集
desciteratorthrouveiterator(集);
//通过对于每个人遍历树集。不推荐!此方法需要先将一组转换为数组
foreachTreeSet(set);
}
//顺序遍历树集
公共静态void asciiteratorthroughiterator(树集集){
System.out.print('\n -升序迭代器-\ n ');
for(迭代器ITER=集。迭代器();ITER。有next();) {
' asc : %s\n ',ITER。next());
}
}
//逆序遍历树集
公共静态void desciteratorthrougheiterator(树集集){
System.out.printf('\n -降序迭代器-\ n ');
for(迭代器ITER=集。降序迭代器();ITER。有next();)
System.out.printf('desc : %s\n ',(字符串)ITER。next());
}
//通过对于每个人遍历树集。不推荐!此方法需要先将一组转换为数组
私有静态void foreachTreeSet(TreeSet){
系统。出去。printf(' \ n-For-each-\ n ');
String[]arr=(String[])集。to数组(新字符串[0]);
对于(字符串字符串:arr)
系统。出去。printf(' for each:% s \ n ',str);
}
}
运行结果:
-升序迭代器-
asc : aaa
asc : bbb
asc : ccc
asc : ddd
asc : eee
-下降迭代器-
desc : eee
desc:国内直拨电话
desc : ccc
desc : bbb
desc : aaa
-为了-每一个-
每个:aaa
每个:bbb
每个:ccc
每个:ddd
每个:eee
第5部分 TreeSet示例
下面通过实例学习如何使用树集
导入Java。util。*;
/**
* @desc树集的应用程序接口测试
*
* @作者天行
* @电子邮件kuiwu-wang@163.com
*/
公共类TreeSetTest {
公共静态void main(String[] args) {
testTreeSetAPIs();
}
//测试树集的美国石油学会(美国石油协会)
公共静态void testTreeSetAPIs() {
字符串值;
//新建树集
TreeSet tSet=new TreeSet();
//将元素添加到树集中
tset。add(' AAA ');
//设置中不允许重复元素,所以只会保存一个“aaa”
tset。add(' AAA ');
tset。add(' BBB ');
tset。add(“eee”);
tset。添加(' DDD ');
tset。添加(“CCC”);
系统。出去。println(' TreeSet:' tSet ');
//打印树集的实际大小
System.out.printf('size : %d\n ',tset。size());
//导航方法
//楼层(小于、等于)
系统。出去。printf(' floor BBB:% s \ n ',tset。地板(' BBB ');
//降低(小于)
系统。出去。printf('低位BBB:% s \ n ',tset。较低(' BBB ');
//天花板(大于、等于)
系统。出去。printf('上限BBB:% s \ n ',tset。天花板(“BBB”);
系统。出去。printf('上限eee:% s \ n ',tset。天花板(“eee”);
//天花板(大于)
系统。出去。printf('更高的BBB:% s \ n ',tset。更高(' BBB ');
//子集()
System.out.printf('subSet(aaa,true,ccc,true): %s\n ',tSet.subSet('aaa ',true,' ccc ',true));
System.out.printf('subSet(aaa,true,ccc,false): %s\n ',tSet.subSet('aaa ',true,' ccc ',false));
System.out.printf('subSet(aaa,false,ccc,true): %s\n ',tSet.subSet('aaa ',false,' ccc ',true));
System.out.printf('subSet(aaa,false,ccc,false): %s\n ',tSet.subSet('aaa ',false,' ccc ',false));
//耳机()
System.out.printf('headSet(ccc,true): %s\n ',tSet.headSet('ccc,true));
System.out.printf('headSet(ccc,false): %s\n ',tSet.headSet('ccc ',false));
//tailSet()
System.out.printf('tailSet(ccc,true): %s\n ',tSet.tailSet('ccc ',true));
System.out.printf('tailSet(ccc,false): %s\n ',tSet.tailSet('ccc ',false));
//删除" ccc "
tset。移除(“CCC”);
//将一组转换为数组
String[]arr=(String[])tset。to数组(新字符串[0]);
对于(字符串字符串:arr)
系统。出去。printf(' for each:% s \ n ',str);
//打印树集
系统。出去。printf(' TreeSet:% s \ n ',tSet);
//遍历树集
for(迭代器ITER=tset。迭代器();ITER。有next();) {
' iter : %s\n ',iter。next());
}
//删除并返回第一个元素
val=(String)tset。先投票();
系统。出去。printf(' poll first=% s,set=%s\n ',val,tSet);
//删除并返回最后一个元素
val=(String)tset。poll last();
System.out.printf('pollLast=%s,set=%s\n ',val,tSet);
//清空哈希特
tset。clear();
//输出哈希特是否为空
System.out.printf('%s\n ',tSet.isEmpty()?“集为空”:“集不为空”);
}
}
运行结果:
树集:[aaa、bbb、ccc、ddd、eee]
尺寸:5
血脑屏障楼层:bbb
下bbb: aaa
天花板bbb: bbb
天花板eee: eee
高bbb: ccc
子集(aaa,true,ccc,true): [aaa,bbb,ccc]
子集(aaa,真,ccc,假):[aaa,bbb]
子集(aaa,false,ccc,true): [bbb,ccc]
子集(aaa,false,ccc,false): [bbb]
耳机(ccc,true): [aaa,bbb,ccc]
耳机(ccc,假):[aaa,bbb]
tailSet(ccc,true): [ccc,ddd,eee]
tailSet(ccc,false): [ddd,eee]
每个:aaa
每个:bbb
每个:ddd
每个:eee
树集:[aaa,bbb,ddd,eee]
iter : aaa
iter : bbb
iter : ddd
iter : eee
pollFirst=aaa,set=[bbb,ddd,eee]
pollLast=eee,set=[bbb,ddd]
集合为空
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。