java.util.TreeSet源码分析

public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable

TreeSet的实现基于TreeMap,元素的顺序取决于元素自然顺序或者在被创建出来时提供的比较器。

对于基本操作,add、remove、contains的时间复杂度为logn。

不是线程安全的,如果在多线程环境下,必须被同步化,可通过一个object作为锁来同步,或者使用Collections.synchronizedSortedSet(new TreeSet(...));方法同步。

迭代器方法是快速失败的,保证错误尽快地被发现。

private transient NavigableMap<E,Object> m;

// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

TreeSet内部维护的是一个NavigableMap,通常会是一个TreeMap,PRESENT是作为Map所有键值对的值。

5个构造器:

TreeSet(NavigableMap<E,Object> m) {
    this.m = m;
}

public TreeSet() {
    this(new TreeMap<E,Object>());
}

public TreeSet(Comparator<? super E> comparator) {
    this(new TreeMap<>(comparator));
}

public TreeSet(Collection<? extends E> c) {
    this();
    addAll(c);
}

public TreeSet(SortedSet<E> s) {
    this(s.comparator());
    addAll(s);
}

2个迭代器:

//递增的迭代器
public Iterator<E> iterator() {
    return m.navigableKeySet().iterator();
}

//递减的迭代器
public Iterator<E> descendingIterator() {
    return m.descendingKeySet().iterator();
}
//返回递减的Set
public NavigableSet<E> descendingSet() {
    return new TreeSet<>(m.descendingMap());
}
//插入成功返回true,失败或者已存在返回false
public boolean add(E e) {
    return m.put(e, PRESENT)==null;
}

//删除成功返回true,否则返回false
public boolean remove(Object o) {
    return m.remove(o)==PRESENT;
}

//判断是否包含o这个元素
public boolean contains(Object o) {
    return m.containsKey(o);
}
//返回集合的子集,两个boolean表示是否包含边界
public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
                                  E toElement,   boolean toInclusive) {
        return new TreeSet<>(m.subMap(fromElement, fromInclusive,
                                       toElement,   toInclusive));
}

//还有其他一些headSet,tailSet,与subSet类似

可以返回比较器:

public Comparator<? super E> comparator() {
    return m.comparator();
}
//返回第一个元素
public E first() {
        return m.firstKey();
    }

//返回最后一个元素
public E last() {
        return m.lastKey();
    }

//返回小于e的最大的元素
public E lower(E e) {
        return m.lowerKey(e);
    }

//返回小于等于e的最大元素
public E floor(E e) {
        return m.floorKey(e);
    }

//返回大于等于e的最小元素
public E ceiling(E e) {
        return m.ceilingKey(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);
    }
时间: 2024-10-14 14:06:52

java.util.TreeSet源码分析的相关文章

java.util.AbstractStringBuilder源码分析

AbstractStringBuilder是一个抽象类,是StringBuilder和StringBuffer的父类,分析它的源码对StringBuilder和StringBuffer代码的理解有很大的帮助. 先来看看该类的声明: abstract class AbstractStringBuilder implements Appendable, CharSequence {} 该类实现Appendable和CharSequence接口. 成员变量: char[] value;//字符数组用来

java.util.ArrayList源码分析

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable 可变数组大小的List实现,允许所有的元素,包括null.(该类可粗略地看作是Vector,除了它不是同步化的) size.isEmpty.get.set.iterator和listIterator操作的运行时间是常量.add操作对于添加n个

java.util.HashSet源码分析

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable HashSet实现Set接口,内部维护一个HashMap实例变量.不保证顺序,允许null元素. 对于基本的操作,如add,remove,contains,size,只需要常量的时间复杂度. 不是线程安全的,如果在多线程环境下,需要被同步化,如调用方法Collections.s

java.util.Map源码分析

/** * An object that maps keys to values. A map cannot contain duplicate keys; * each key can map to at most one value. * * <p>This interface takes the place of the <tt>Dictionary</tt> class, which * was a totally abstract class rather t

java.util.TreeMap源码分析

TreeMap的实现基于红黑树,排列的顺序根据key的大小,或者在创建时提供的比较器,取决于使用哪个构造器. 对于,containsKey,get,put,remove操作,保证时间复杂度为log(n). TreeMap的顺序与equals方法保持一致,这样才能遵守Map和SortMap的约定. 实现非同步,运行在多线程环境下,要进行外部同步,或者调用SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));方法得到一个同

java.io.BufferedOutputStream 源码分析

BufferedOutputStream  是一个带缓冲区到输出流,通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统. 俩个成员变量,一个是存储数据的内部缓冲区,一个是缓冲区中的有效字节数. /** * The internal buffer where data is stored. */ protected byte buf[]; /** * The number of valid bytes in the buffer. This value

Java split方法源码分析

Java split方法源码分析 1 public String[] split(CharSequence input [, int limit]) { 2 int index = 0; // 指针 3 boolean matchLimited = limit > 0; // 是否限制匹配个数 4 ArrayList<String> matchList = new ArrayList<String>(); // 匹配结果队列 5 Matcher m = matcher(inp

【JAVA】ThreadLocal源码分析

ThreadLocal内部是用一张哈希表来存储: 1 static class ThreadLocalMap { 2 static class Entry extends WeakReference<ThreadLocal<?>> { 3 /** The value associated with this ThreadLocal. */ 4 Object value; 5 6 Entry(ThreadLocal<?> k, Object v) { 7 super(k)

死磕 java集合之TreeSet源码分析

问题 (1)TreeSet真的是使用TreeMap来存储元素的吗? (2)TreeSet是有序的吗? (3)TreeSet和LinkedHashSet有何不同? 简介 TreeSet底层是采用TreeMap实现的一种Set,所以它是有序的,同样也是非线程安全的. 源码分析 经过前面我们学习HashSet和LinkedHashSet,基本上已经掌握了Set实现的套路了. 所以,也不废话了,直接上源码: package java.util; // TreeSet实现了NavigableSet接口,所