zoukankan      html  css  js  c++  java
  • TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?


    原创LiQiyaoo
    展开
    TreeMap和TreeSet都是有序的集合。

    TreeSet要求集合中的元素实现Comparable接口,并实现compareTo方法进行比较,如果compareTo方法实现的不好,可能会导致元素插入失败,因为集合内部也通过compareTo方法来比较元素是否相等(而不是通过equals),即判断一个元素是否可插入。

    TreeMap要求键列的元素实现Comparable接口,与TreeSet对元素的要求一样。

    TreeSet其实内部是通过一个TreeMap来实现的,用了组合的设计模式。

    我们来看下源码

    /**
    * The backing map.
    */
    private transient NavigableMap<E,Object> m;

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

    public TreeSet() {
    this(new TreeMap<E,Object>());
    }
    可以看到,在构造TreeSet时,也构造了一个TreeMap,并且Map中的value不使用。
    我们调用TreeSet的add方法,其实是调用了TreeMap的put方法,我们再看一下源码。

    public boolean add(E e) {
    return m.put(e, PRESENT)==null;
    }
    PRESENT是一个Object对象,没有实际意义,现在我们进入TreeMap看一下put方法的源码。

    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;
    }
    我们可以看到,方法内是通过元素实现Comparable接口并实现了的compareTo方法来比较两个key是否相等的。并且进行排序。
    第二个问题:

    Collections有两个sort方法,可以仅仅传入一个由实现了Comparable接口元素构成的List对象,当然也可以传入集合中的元素没有实现Comparable的List对象,但是要求传入第二个参数,参数是Comparator接口的子类型(需要重写compare方法实现元素的比较),相当于一个临时定义的排序规则,其实就是通过接口注入比较元素大小的算法,也是对回调模式的应用(Java中对函数式编程的支持)。

    另外一点,

    Collection和Collections有很大区别,Collection是 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。

    而Collections是一个包装类,包装了许多操作集合的静态方法。就相当于一个工具类。
    ————————————————
    版权声明:本文为CSDN博主「LiQiyaoo」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/L_BestCoder/article/details/77771412

  • 相关阅读:
    在ubuntu上搭建turnserver
    如何将R包安装到自定义路径
    R读取MySQL数据出现乱码,解决该问题的方法总结
    利用百度API(js),通过地址获取经纬度的注意事项
    通过地址获取经纬度的三种方法; 通过经纬度获取省市的方法
    软件工程-第一周作业汇总
    软件工程作业-采访本课程往届学生记录
    动手实现混合四则运算
    历年学生软件作品点评
    软件工程-东北师大站-第一次作业
  • 原文地址:https://www.cnblogs.com/fangdie/p/12607384.html
Copyright © 2011-2022 走看看