zoukankan      html  css  js  c++  java
  • 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);
        }
  • 相关阅读:
    c语言数据处理!
    指针的概念
    return的用处
    用java写随机出题
    java 新手
    分支程序设计。
    不同车型 不同起步价不同费用的问题(switch语句)
    这两天做了很多随机函数的用法(下面是一个出题实验)。
    yum 命令讲解
    日常工作中一些常用命令
  • 原文地址:https://www.cnblogs.com/13jhzeng/p/5797728.html
Copyright © 2011-2022 走看看