TreeSet 源码分析
Posted zhuxudong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TreeSet 源码分析相关的知识,希望对你有一定的参考价值。
package java.util;
/**
* 1)基于 TreeMap 的 {@link NavigableSet} 接口实现, TreeSet 使用自然顺序或指定的比较器对元素进行排序。
* 2)基本操作 {@code add}、{@code remove}、{@code contains} 的时间复杂度为 log(n)。
* 3)TreeSet 中的元素必须实现 Comparable 接口,定义良好的 equals 和 hashCode 方法可以均匀分散元素。
* 4)TreeSet 实现不是同步的,多个线程并发修改 TreeSet 必须在外部实现同步。
* <pre>
* SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));
* </pre>
* 5)TreeSet 返回的迭代器是快速失败的,多线程并发访问时,如果至少有一个线程从结构上修改了
* TreeSet,而不是通过迭代器自身的 remove 方法,则迭代器将抛出 ConcurrentModificationException 异常。
*/
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable {
/**
* The backing map.
* 支持 TreeSet 的 NavigableMap 实现
*/
private transient NavigableMap<E, Object> m;
// Dummy value to associate with an Object in the backing Map
// TreeSet 中的傀儡对象,用作占位符
private static final Object PRESENT = new Object();
/**
* Constructs a set backed by the specified navigable map.
* 创建由指定的 NavigableMap 实现支持的 TreeSet 对象
*/
TreeSet(NavigableMap<E, Object> m) {
this.m = m;
}
/**
* 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}.
* 创建一个新的空 TreeSet,TreeSet 中的元素根据自然顺序进行排序,
* 元素必须实现 Comparable 接口。
*/
public TreeSet() {
this(new TreeMap<>());
}
/**
* 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}.
* 创建一个新的空 TreeSet,TreeSet 中的元素根据指定的比较器 comparator 进行排序,
* 元素必须实现 Comparable 接口。
*
*/
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
/**
* 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.
* 创建一个新的空 TreeSet,TreeSet 中的元素根据自然顺序进行排序,
* 元素必须实现 Comparable 接口,并将集合 c 中的所有元素都添加到 TreeSet 中。
*/
public TreeSet(Collection<? extends E> c) {
this();
this.addAll(c);
}
/**
* Constructs a new tree set containing the same elements and using the same ordering as the specified sorted set.
* 根据指定的 SortedSet 实例创建 TreeSet 实例。
*/
public TreeSet(SortedSet<E> s) {
this(s.comparator());
this.addAll(s);
}
/**
* Returns an iterator over the elements in this set in ascending order.
* 返回 TreeSet 中所有元素的升序迭代器
*/
public Iterator<E> iterator() {
return this.m.navigableKeySet().iterator();
}
/**
* Returns an iterator over the elements in this set in descending order.
* 返回 TreeSet 中所有元素的降序迭代器
*/
public Iterator<E> descendingIterator() {
return this.m.descendingKeySet().iterator();
}
/**
* 返回降序 Set
*/
public NavigableSet<E> descendingSet() {
return new TreeSet<>(this.m.descendingMap());
}
/**
* Returns the number of elements in this set (its cardinality).
* 返回 TreeSet 中的元素总数
*/
public int size() {
return this.m.size();
}
/**
* Returns {@code true} if this set contains no elements.
* TreeSet 是否为空
*/
public boolean isEmpty() {
return this.m.isEmpty();
}
/**
* 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 {@code Objects.equals(o, e)}.
* TreeSet 中是否包含指定的目标对象 o
*/
public boolean contains(Object o) {
return this.m.containsKey(o);
}
/**
* 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 {@code Objects.equals(e, e2)}. If this
* set already contains the element, the call leaves the set unchanged and returns {@code false}.
* 将目标对象 o 添加到 TreeSet 中
*/
public boolean add(E e) {
return this.m.put(e, TreeSet.PRESENT) == null;
}
/**
* Removes the specified element from this set if it is present. More formally, removes an element {@code e} such
* that {@code Objects.equals(o, e)}, 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.)
* 从 TreeSet 中移除目标对象 o
*/
public boolean remove(Object o) {
return this.m.remove(o) == TreeSet.PRESENT;
}
/**
* Removes all of the elements from this set. The set will be empty after this call returns.
* 移除 TreeSet 中的所有元素
*/
public void clear() {
this.m.clear();
}
/**
* Adds all of the elements in the specified collection to this set.
* 将目标集合 c 中的所有元素添加到 TreeSet 中
*/
public boolean addAll(Collection<? extends E> c) {
// Use linear-time version if applicable
if ((this.m.size() == 0) && (c.size() > 0) && (c instanceof SortedSet) && (this.m instanceof TreeMap)) {
final SortedSet<? extends E> set = (SortedSet<? extends E>) c;
final TreeMap<E, Object> map = (TreeMap<E, Object>) this.m;
final Comparator<?> cc = set.comparator();
final Comparator<? super E> mc = map.comparator();
if ((cc == mc) || ((cc != null) && cc.equals(mc))) {
map.addAllForTreeSet(set, TreeSet.PRESENT);
return true;
}
}
return super.addAll(c);
}
/**
* 获取当前 TreeSet 的子视图
* @param fromElement 起始元素
* @param fromInclusive 是否包含起始元素
* @param toElement 结束元素
* @param toInclusive 是否包含结束元素
* @return
*/
public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
return new TreeSet<>(this.m.subMap(fromElement, fromInclusive, toElement, toInclusive));
}
/**
* 获取 TreeSet 的头部子视图
*/
public NavigableSet<E> headSet(E toElement, boolean inclusive) {
return new TreeSet<>(this.m.headMap(toElement, inclusive));
}
/**
* 获取 TreeSet 的尾部子视图
*/
public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
return new TreeSet<>(this.m.tailMap(fromElement, inclusive));
}
/**
* 获取 TreeSet 的子视图,包括开始元素,不包括结束元素
*/
public SortedSet<E> subSet(E fromElement, E toElement) {
return this.subSet(fromElement, true, toElement, false);
}
/**
* 获取 TreeSet 的头部子视图,不包括结束元素
*/
public SortedSet<E> headSet(E toElement) {
return this.headSet(toElement, false);
}
/**
* 获取 TreeSet 的尾部子视图,不包括起始元素
*/
public SortedSet<E> tailSet(E fromElement) {
return this.tailSet(fromElement, true);
}
public Comparator<? super E> comparator() {
return this.m.comparator();
}
/**
* 获取 TreeSet 的第一个元素
*/
public E first() {
return this.m.firstKey();
}
/**
* 获取 TreeSet 的最后一个元素
*/
public E last() {
return this.m.lastKey();
}
// NavigableSet API methods:参考 TreeMap
public E lower(E e) {
return this.m.lowerKey(e);
}
public E floor(E e) {
return this.m.floorKey(e);
}
public E ceiling(E e) {
return this.m.ceilingKey(e);
}
public E higher(E e) {
return this.m.higherKey(e);
}
public E pollFirst() {
Map.Entry<E, ?> e = this.m.pollFirstEntry();
return (e == null) ? null : e.getKey();
}
public E pollLast() {
Map.Entry<E, ?> e = this.m.pollLastEntry();
return (e == null) ? null : e.getKey();
}
@SuppressWarnings("unchecked")
public Object clone() {
TreeSet<E> clone;
try {
clone = (TreeSet<E>) super.clone();
} catch (final CloneNotSupportedException e) {
throw new InternalError(e);
}
clone.m = new TreeMap<>(this.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(this.m.comparator());
// Write out size
s.writeInt(this.m.size());
// Write out all elements in the proper order.
for (final E e : this.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")
final Comparator<? super E> c = (Comparator<? super E>) s.readObject();
// Create backing TreeMap
final TreeMap<E, Object> tm = new TreeMap<>(c);
this.m = tm;
// Read in size
final int size = s.readInt();
tm.readTreeSet(size, s, TreeSet.PRESENT);
}
/**
* Creates a <em><a href="Spliterator.html#binding">late-binding</a></em> and <em>fail-fast</em> {@link Spliterator}
* over the elements in this set.
* <p>
* The {@code Spliterator} reports {@link Spliterator#SIZED}, {@link Spliterator#DISTINCT},
* {@link Spliterator#SORTED}, and {@link Spliterator#ORDERED}. Overriding implementations should document the
* reporting of additional characteristic values.
* <p>
* The spliterator‘s comparator (see {@link java.util.Spliterator#getComparator()}) is {@code null} if the tree
* set‘s comparator (see {@link #comparator()}) is {@code null}. Otherwise, the spliterator‘s comparator is the same
* as or imposes the same total ordering as the tree set‘s comparator.
*
* @return a {@code Spliterator} over the elements in this set
* @since 1.8
*/
public Spliterator<E> spliterator() {
return TreeMap.keySpliteratorFor(this.m);
}
private static final long serialVersionUID = -2479143000061671589L;
}
以上是关于TreeSet 源码分析的主要内容,如果未能解决你的问题,请参考以下文章