zoukankan      html  css  js  c++  java
  • Java基础知识强化之集合框架笔记44:Set集合之TreeSet保证元素唯一性和自然排序的原理和图解

    1. TreeSet保证元素唯一性和自然排序的原理和图解

    2. TreeSet唯一性以及有序性底层剖析:

    通过观察TreeSet的add()方法,我们知道最终要看TreeMap的put()方法。

    跟踪进入源码:

     1 interface Collection {...}
     2 
     3 interface Set extends Collection {...}
     4 
     5 interface NavigableMap {
     6 
     7 }
     8 
     9 class TreeMap implements NavigableMap {
    10      public V put(K key, V value) {
    11         Entry<K,V> t = root;
    12         if (t == null) {
    13             compare(key, key); // type (and possibly null) check
    14 
    15             root = new Entry<>(key, value, null);
    16             size = 1;
    17             modCount++;
    18             return null;
    19         }
    20         int cmp;
    21         Entry<K,V> parent;
    22         // split comparator and comparable paths
    23         Comparator<? super K> cpr = comparator;
    24         if (cpr != null) {
    25             do {
    26                 parent = t;
    27                 cmp = cpr.compare(key, t.key);
    28                 if (cmp < 0)
    29                     t = t.left;
    30                 else if (cmp > 0)
    31                     t = t.right;
    32                 else
    33                     return t.setValue(value);
    34             } while (t != null);
    35         }
    36         else {
    37             if (key == null)
    38                 throw new NullPointerException();
    39             Comparable<? super K> k = (Comparable<? super K>) key;
    40             do {
    41                 parent = t;
    42                 cmp = k.compareTo(t.key);
    43                 if (cmp < 0)
    44                     t = t.left;
    45                 else if (cmp > 0)
    46                     t = t.right;
    47                 else
    48                     return t.setValue(value);
    49             } while (t != null);
    50         }
    51         Entry<K,V> e = new Entry<>(key, value, parent);
    52         if (cmp < 0)
    53             parent.left = e;
    54         else
    55             parent.right = e;
    56         fixAfterInsertion(e);
    57         size++;
    58         modCount++;
    59         return null;
    60     }
    61 }
    62 
    63 class TreeSet implements Set {
    64     private transient NavigableMap<E,Object> m;
    65     
    66     public TreeSet() {
    67          this(new TreeMap<E,Object>());
    68     }
    69 
    70     public boolean add(E e) {
    71         return m.put(e, PRESENT)==null;
    72     }
    73 }

    总结:

    真正的比较是依赖于元素的compareTo()方法,而这个方法是定义在 Comparable里面的。所以,你要想重写该方法,就必须是先 Comparable接口。这个接口表示的就是自然排序。

    通过观察TreeSet的底层源码发现,TreeSet的add(E e)方法,底层是根据实现Comparable的方式来实现的唯一性,通过compare(Object o)的返回值是否为0来判断是否为同一元素。 
    compare() == 0,元素不入集合。 
    compare() > 0 ,元素入右子树。 
    compare() < 0,元素入左子树。 
    而对其数据结构:自平衡二叉树做前(常用)、中、后序遍历即可保证TreeSet的有序性。

  • 相关阅读:
    【好文翻译】10个免费的压力测试工具(Web)
    【高手介绍】谷歌内部代码审查(code review)介绍[翻译]
    【淘宝内部好文转发】我们每天面对的互联网用户到底在想什么?
    写给开发者:别让他人用你的App赚钱[转]
    新手应该知道的二十三条关于JavaScript的最佳实践
    开发人员应该为这样的代码感到惭愧
    [Web App]必胜客宅急送产品设计思路介绍[转]
    WallsEveryDay 必应桌面壁纸
    GroupLayout 布局
    JButton 做图片框
  • 原文地址:https://www.cnblogs.com/hebao0514/p/4857659.html
Copyright © 2011-2022 走看看