TreeSet集合处于降序模式时的高()方法的行为?

时间:2013-10-19 14:12:36

标签: java collections

当TreeSet集合的lower()方法按降序排序时,是否有任何正文可以描述此行为:

代码:

NavigableSet<Integer> set = new TreeSet<>();

set.add(10);
set.add(22);
set.add(34);
set.add(40);
set.add(45);
set.add(56);
set.add(77);
set.add(79);
set.add(84);
set.add(99);

set = set.descendingSet();

System.out.printf("%n Higher than 40 : %s", set.higher(40));

返回以下结果即

Higher than 40 : 34

现在,虽然收集按降序排序仍然higher(40)方法应该返回一个高于40的值(当然是45)?

1 个答案:

答案 0 :(得分:5)

  • set.higher(T):函数返回此集合中的最小元素严格大于给定元素,如果没有这样的元素,则返回null

  • set.descendingSet():返回此view中包含的元素的反向顺序set

究竟发生了什么?

TreeSet固有地使用TreeMap来实现其功能。对descendingSet()的调用最终会调用descendingMap()实例上的TreeMap函数,如以下源代码所示:

public NavigableSet<E> descendingSet() {
        return new TreeSet<>(m.descendingMap());
    }

每个TreeMap通常都会保留两个视图:

  • 正常排序视图:使用通用比较器对其元素进行排序
  • 后代地图视图:使用比较器,它对上升顺序比较器施加反向排序。它使用Collections.reverseOrder(m.comparator())来返回这个降序排序比较器。

我正在调用这些view,因为TreeMap实际上并没有用它的条目(键,值)创建另一个后代Map,而是保持两个比较器,相反相互排序。在调用descendantMap()时,第一次创建后代视图。对此函数的任何后续调用都将返回相同的后代Map视图。

注意: set.descendingSet().descendingSet()返回的set视图基本上等同于set。因为第一次调用的结果比较器在descendingSet()的第二次调用(实际上在内部执行map.descendingMap())中再次反转

继续您的示例:

System.out.printf("%n Higher than 40 : %s", set.higher(40)); // prints 45
set = set.descendingSet(); // create a reverse ordering 
                           //comparator as described above 
System.out.printf("%n Higher than 40 : %s", set.higher(40)); // prints 34
set = set.descendingSet(); // again trying to get descending set!
System.out.printf("%n Higher than 40 : %s", set.higher(40))  // prints 45