排序set,排序map
TreeSet:当我们使用无参构造器,创建 TreeSet 时,默认调用添加对象的类的Compareto方法进行排序,如果传入的Key对象没有实现Comparable接口,会抛出classCastException。比如:传入的Key为String类型,那么就会调用String类里面的compareTo()方法。只有实现了Comparable接口的类对象才能加入到TreeSet中,否则就会报classCastException异常
public static void main(String[] args) { TreeSet treeSet = new TreeSet(); treeSet.add("jack"); treeSet.add("tom"); treeSet.add("sp"); treeSet.add("a"); System.out.println(treeSet); }
调用类的Compareto方法
调用有参构造,可以传入Compartor对象,使用匿名内部类对象
TreeSet treeSet = new TreeSet(new Comparator() { @Override public int compare(Object o1, Object o2) { return ((String) o1).compareTo((String)o2); } });
源码解析:
1.构造器. 把传入的实现了 Comparator 接口的匿名内部类(对象),传给给 TreeMap 的 comparator
public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator)); } public TreeMap(Comparator<? super K> comparator) { this.comparator = comparator; }
2.调用put方法,第一次添加, 把 k-v 封装到 Entry 对象,放入 root
Entry<K,V> t = root; if (t == null) { compare(key, key); // 这一步的目的就是检查空值,如果有null则报异常 root = new Entry<>(key, value, null); size = 1; modCount++; return null; }
之后添加元素,才会用到Comparator
Comparator<? super K> cpr = comparator; if (cpr != null) { do {//遍历所有的 key , 给当前 key 找到适当位置 parent = t; cmp = cpr.compare(key, t.key);//动态绑定到我们的匿名内部类的 compare if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else//如果遍历过程中,发现准备添加 Key 和当前已有的 Key 相等,就不添加 //对于TreeSet来说,value固定为PRESENT,重新设置value没有任何作用,相当于没添加 return t.setValue(value); } while (t != null); }
对于TreeSet而言,遇到cmp == 0 则不会添加,而对于TreeMap而言,遇到cmp == 0 的情况时,会进行value值 的覆盖
Java 集合框架(TreeSet 和 TreeMap)
最新推荐文章于 2021-07-30 18:19:56 发布