树集集合的 high() 方法在降序模式下的行为



当按降序排序时,任何机构都可以描述 TreeSet 集合的 high() 方法的这种行为:

法典:

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)的值?

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

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

到底发生了什么?

TreeSet本质上使用 TreeMap 来实现其功能。对descendingSet()的调用最终调用TreeMap实例上的 descendingMap() 函数,从以下源代码中可以明显看出:

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

最新更新