java.util.TreeSet源码分析
TreeSet是基于TreeMap实现的,元素的顺序取决于元素自身的自然顺序或者在构造时提供的比较器。
对于add,remove,contains操作,保证log(n)的时间复杂度。
因为Set接口的定义根据equals方法,但是TreeSet接口约定元素的顺序基于compareTo或者compare方法,所以它们要保持一致性才能保证程序不会出错。
TreeSet不是同步化的,运行在多线程环境下需要外部同步化或调用SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));方法。
迭代器是快速失败的。
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable
实例变量
//TreeSet的实现基于TreeMap(TreeMap实现NavigableMap),内部维护一个NavigableMap
private transient NavigableMap<E,Object> m; //作用是把TreeSet的元素存入TreeMap中时,元素作为键,PRESENT作为值
private static final Object PRESENT = new Object();
构造器
//这个构造器不是导出API,在下面构造器有使用这个构造器
TreeSet(NavigableMap<E,Object> m) {
this.m = m;
} //调用第一个的构造器,创建一个空的TreeSet,不提供比较器,使用元素自然顺序
public TreeSet() {
this(new TreeMap<E,Object>());
} //调用第一个构造器,提供比较器,比较器由TreeMap维护,TreeSet本身没有比较器
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
} //通过Collection的子类构造TreeSet,不提供比较器,使用元素的自然顺序
public TreeSet(Collection<? extends E> c) {
this();
addAll(c);
} //通过SortedSet的子类构造TreeSet,SortedSet本身可能有比较器,如果有,使用该比较器,否则使用元素自然顺序
public TreeSet(SortedSet<E> s) {
this(s.comparator());
addAll(s);
}
迭代器
//返回升序迭代器
public Iterator<E> iterator() {
return m.navigableKeySet().iterator();
} //返回降序迭代器
public Iterator<E> descendingIterator() {
return m.descendingKeySet().iterator();
}
返回一个降序的TreeSet
public NavigableSet<E> descendingSet() {
return new TreeSet<>(m.descendingMap());
}
一些基本操作
//Set含有的元素个数
public int size() {
return m.size();
} //判断是否为空,其实就是size会否为0
public boolean isEmpty() {
return m.isEmpty();
} //Set是否包含元素o
public boolean contains(Object o) {
return m.containsKey(o);
} //增加一个元素,可以看到e作为键,PRESENT作为值
public boolean add(E e) {
return m.put(e, PRESENT)==null;
} //删除一个元素,根据删除返回的结果是否和PRESENT等同来返回是否删除成功
public boolean remove(Object o) {
return m.remove(o)==PRESENT;
} //清空Set
public void clear() {
m.clear();
}
返回子集合的操作
//fromElement开始元素,toElement结束元素,fromInclusive,toInclusive表示是否包含边界,跟下面的返回子集合操作的参数意义一样
public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
E toElement, boolean toInclusive) {
return new TreeSet<>(m.subMap(fromElement, fromInclusive,
toElement, toInclusive));
} public NavigableSet<E> headSet(E toElement, boolean inclusive) {
return new TreeSet<>(m.headMap(toElement, inclusive));
} public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
return new TreeSet<>(m.tailMap(fromElement, inclusive));
} public SortedSet<E> subSet(E fromElement, E toElement) {
return subSet(fromElement, true, toElement, false);
} public SortedSet<E> headSet(E toElement) {
return headSet(toElement, false);
} public SortedSet<E> tailSet(E fromElement) {
return tailSet(fromElement, true);
}
返回比较器
public Comparator<? super E> comparator() {
return m.comparator();
}
返回某些特定元素的操作
//返回集合的第一个元素
public E first() {
return m.firstKey();
} //返回集合的最后一个元素
public E last() {
return m.lastKey();
} //返回比e小的最大元素,不包括e
public E lower(E e) {
return m.lowerKey(e);
} //返回比e小的最大元素,包括e
public E floor(E e) {
return m.floorKey(e);
} //返回比e大的最小元素,包括e
public E ceiling(E e) {
return m.ceilingKey(e);
} //返回比e大的最小元素,不包括e
public E higher(E e) {
return m.higherKey(e);
} //返回并删除第一个元素
public E pollFirst() {
Map.Entry<E,?> e = m.pollFirstEntry();
return (e == null) ? null : e.getKey();
} //返回并删除最后一个元素
public E pollLast() {
Map.Entry<E,?> e = m.pollLastEntry();
return (e == null) ? null : e.getKey();
}
支持clone
public Object clone() {
TreeSet<E> clone;
try {
clone = (TreeSet<E>) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
clone.m = new TreeMap<>(m);
return clone;
}
支持序列化和反序列化
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// Write out any hidden stuff
s.defaultWriteObject(); // Write out Comparator
s.writeObject(m.comparator()); // Write out size
s.writeInt(m.size()); // Write out all elements in the proper order.
for (E e : m.keySet())
s.writeObject(e);
} private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden stuff
s.defaultReadObject(); // Read in Comparator
@SuppressWarnings("unchecked")
Comparator<? super E> c = (Comparator<? super E>) s.readObject(); // Create backing TreeMap
TreeMap<E,Object> tm = new TreeMap<>(c);
m = tm; // Read in size
int size = s.readInt(); tm.readTreeSet(size, s, PRESENT);
}
java.util.TreeSet源码分析的更多相关文章
- java.util.Collection源码分析和深度讲解
写在开头 java.util.Collection 作为Java开发最常用的接口之一,我们经常使用,今天我带大家一起研究一下Collection接口,希望对大家以后的编程以及系统设计能有所帮助,本文所 ...
- java.util.HashMap源码分析
在java jdk8中对HashMap的源码进行了优化,在jdk7中,HashMap处理“碰撞”的时候,都是采用链表来存储,当碰撞的结点很多时,查询时间是O(n). 在jdk8中,HashMap处理“ ...
- java.util.AbstractStringBuilder源码分析
AbstractStringBuilder是一个抽象类,是StringBuilder和StringBuffer的父类,分析它的源码对StringBuilder和StringBuffer代码的理解有很大 ...
- java.util.Hashtable源码分析
Hashtable实现一个键值映射的表.任何非null的object可以用作key和value. 为了能存取对象,放在表里的对象必须实现hashCode和equals方法. 一个Hashtable有两 ...
- java.util.Dictionary源码分析
Dictionary是一个抽象类,Hashtable是它的一个子类. 类的声明:/** The <code>Dictionary</code> class is the abs ...
- java.util.TreeMap源码分析
TreeMap的实现基于红黑树,排列的顺序根据key的大小,或者在创建时提供的比较器,取决于使用哪个构造器. 对于,containsKey,get,put,remove操作,保证时间复杂度为log(n ...
- java.util.LinkedList源码分析
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, D ...
- java.util.ArrayList源码分析
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...
- java.util.HashSet源码分析
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java. ...
随机推荐
- C# 网络通信大小端转换类
本篇文章主要介绍了"C# 网络通信大小端转换类" using System;namespace Framework.NetPackage.Common { /// <summ ...
- java中如何忽略字符串中的转义字符--转载
原文地址:http://my.oschina.net/u/1010578/blog/366252 起因 这几天工作上需要跟另一个同事联调rest接口,我这边是java他是php,返回报文是js ...
- Linux数据归档和解压缩tar,cpio,gzip,bzip,lzma,zip命令使用
转载:http://www.1987.name/659.html 数据压缩归档和备份是系统管理的日常工作,定期备份不可小视,归档和压缩对于系统管理员或是普通用户来说都经常用到的操作,有很多中压缩格式, ...
- Is an MTD device a block device or a char device?
转:http://www.linux-mtd.infradead.org/faq/general.html#L_mtd_what Note, you can find Ukranian transla ...
- Sum of divisors
Problem Description mmm is learning division, she's so proud of herself that she can figure out the ...
- raspberry pi vpn
http://raspberrypihelp.net/tutorials/1-openvpn-server-tutorialhttp://www.jacobsalmela.com/setting-up ...
- Android小项目之十二 设置中心的界面
------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...
- ASP.NET后台注册JS的方法
1. 用Response.Write方法 代码如下: Response.Write("<script type='text/javascript'>alert("hel ...
- 配置多个Log4net实例
应用场景: 控制软件工程拆分为多个子项目,在开发阶段希望每个子项目的日志是单独的.同时又希望日志统一集中定义在Tools(Tools为工具类项目,生成Tools.dll)下,而不是分散在各个子项目中. ...
- 京东2017 C++一面
一面直接跪,日 1. 重写和重载的区别 答的一般 2. C++内存分配方式 不会 3. TCP ...