任何人都可以描述TreeSet集合的Higher()方法的这种行为,当它以降序排序时:
码:
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
现在,尽管collection按降序排序,但
higher(40)
方法是否应该返回大于40的值(当然是45)? 最佳答案
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