zoukankan      html  css  js  c++  java
  • TreeSet源码分析

    TreeSet源码分析

    -----废话不多说先看一段代码

    public class TreeSetTest {
        public static void main(String[] args) {
            TreeSet<Integer> treeSet = new TreeSet<>();
            treeSet.add(3);
            treeSet.add(1);
            treeSet.add(2);
            treeSet.add(4);
            System.out.println(treeSet);
        }
    }
    打印结果:
    [1, 2, 3, 4]

           通过结果我们发现TreeSet自动帮我们把传入的数据排序了,那底层源码是如何实现的呢?

    源码分析核心步骤

    1.TreeSet源码

    public class TreeSet{
        
      private transient NavigableMap<E,Object> m;
      private static final Object PRESENT = new Object();
        
      public TreeSet() {
            this(new TreeMap<E,Object>());
      } 
      
       public boolean add(E e) {
            return m.put(e, PRESENT)==null;
        }
    }

    通过这里的代码片段,我们发现treeSet的add(E e)的传入值其实保存到TreeMap的

    key,而TreeMap的value只是一个Object,那我们看TreeMap的源码的put(key,value)

    2.TreeMap源码

    class TreeMap{
    ​
       public V put(K key, V value) {
            Entry<K,V> t = root;
            if (t == null) {
                compare(key, key); // type (and possibly null) check
    ​
                root = new Entry<>(key, value, null);
                size = 1;
                modCount++;
                return null;
            }
            int cmp;
            Entry<K,V> parent;
            // split comparator and comparable paths
            Comparator<? super K> cpr = comparator;
            if (cpr != null) {
                do {
                    parent = t;
                    cmp = cpr.compare(key, t.key);
                    if (cmp < 0)
                        t = t.left;
                    else if (cmp > 0)
                        t = t.right;
                    else
                        return t.setValue(value);
                } while (t != null);
            }
            else {
                if (key == null)
                    throw new NullPointerException();
                @SuppressWarnings("unchecked")
                    Comparable<? super K> k = (Comparable<? super K>) key;
                do {
                    parent = t;
                    cmp = k.compareTo(t.key);
                    if (cmp < 0)
                        t = t.left;
                    else if (cmp > 0)
                        t = t.right;
                    else
                        return t.setValue(value);
                } while (t != null);
            }
            Entry<K,V> e = new Entry<>(key, value, parent);
            if (cmp < 0)
                parent.left = e;
            else
                parent.right = e;
            fixAfterInsertion(e);
            size++;
            modCount++;
            return null;
        }
        
        
         static final class Entry<K,V> implements Map.Entry<K,V> {
            K key;
            V value;
            Entry<K,V> left;
            Entry<K,V> right;
            Entry<K,V> parent;
            boolean color = BLACK;
         }
    }

    这里我们发现do{}while{}循环里面有个compareTo()不断比较,通过Entry的left和right进行设置顺序

     

    总结:

    1.TreeSet存储的数据不能重复,不然会被后添加的数据覆盖,应该值保存到TreeMap里面的key中

    2.TreeSet存储的数据会自动排序,应为TreeMap的put方法里面有自动排序的功能

     

  • 相关阅读:
    Java IO学习3:字节字符转换流
    Java IO学习8:System类对IO的支持
    设计模式(一)单例模式
    复制excel下拉框的数值
    iis7.5+win2008 出现 HTTP Error 503. The service is unavailable.
    php显示当前数据库名称
    解决secureCRT显示中文为乱码
    Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e23 ' [Microsoft][ODBC SQL
    jquery textSlider 文字滚动
    donetcms与Discuz整合的webconfig设置
  • 原文地址:https://www.cnblogs.com/pingping-joe/p/11024789.html
Copyright © 2011-2022 走看看