使用 SortedMap 和 NavigableMap 保持键排序
SortedMap 添加的方法
JDK 提供了 Map
接口的两个扩展:SortedMap
和 NavigableMap
。 NavigableMap
是 SortedMap
的扩展。这两个接口都由同一个类实现:TreeMap
。 TreeMap
类是红黑树,一种众所周知的数据结构。
SortedMap
和 NavigableMap
按键对它们的键值对进行排序。就像 SortedSet
和 NavigableSet
一样,您需要提供一种比较这些键的方法。您有两个解决方案可以做到这一点:要么您的键的类实现 Comparable
,要么在创建 TreeMap
时为您的键提供一个 Comparator
。如果您提供了一个 Comparator
,即使您的键是可比较的,它也会被使用。
如果您为 SortedMap
或 NavigableMap
选择的实现是 TreeMap
,那么您可以安全地将 keySet()
或 entrySet()
调用的返回的集合转换为 SortedSet
或 NavigableSet
。 NavigableMap
有一个方法,navigableKeySet()
,它返回一个 NavigableSet
的实例,您可以使用它来代替普通的 keySet()
方法。两种方法都返回同一个对象。
firstKey()
和lastKey()
:返回地图中最小的和最大的键;headMap(toKey)
和tailMap(fromKey)
:返回一个SortedMap
,其键严格小于toKey
,或大于或等于fromKey
;subMap(fromKey, toKey)
:返回一个SortedMap
,其键严格小于toKey
,或大于或等于fromKey
。
这些地图是 SortedMap
的实例,并且是此地图支持的视图。对地图所做的任何更改都将在这些视图中看到。这些视图可以更新,但有一个限制:您不能插入超出您构建的地图边界的键。
您可以在以下示例中看到此行为
SortedMap<Integer, String> map = new TreeMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.put(5, "five");
map.put(6, "six");
SortedMap<Integer, String> headMap = map.headMap(3);
headMap.put(0, "zero"); // this line is ok
headMap.put(4, "four"); // this line throws an IllegalArgumentException
NavigableMap 添加的方法
访问特定键或条目
NavigableMap
向 SortedMap
添加了更多方法。第一组方法让您可以访问地图中的特定键和条目。
firstKey()
,firstEntry()
,lastEntry()
和lastKey()
:返回此地图中最小的或最大的键或条目。ceilingKey(key)
,ceilingEntry(key)
,higherKey(key)
,higherEntry(key)
:返回大于提供的键的最小键或条目。ceiling
方法可能会返回一个等于提供的键的键,而higher
方法返回的键严格大于。floorKey(key)
,floorEntry(key)
,lowerKey(key)
,lowerEntry(key)
:返回小于提供的键的最大键或条目。floor
方法可能会返回一个等于提供的键的键,而higher
方法返回的键严格小于。
使用队列式功能访问您的地图
第二组为您提供队列式功能
pollFirstEntry()
:返回并删除最小的条目pollLastEntry()
:返回并删除最大的条目。
以反向顺序遍历您的地图
第三组反转您的地图,就好像它是在反向比较逻辑上构建的一样。
navigableKeySet()
是一个便捷方法,它返回一个NavigableSet
,这样您就不必将keySet()
的结果进行强制类型转换。descendingKeySet()
:返回一个由映射支持的NavigableSet
,您可以在其中以降序进行迭代。descendingMap()
:返回一个具有相同语义的NavigableMap
。
这两个视图都支持元素删除,但您不能通过它们添加任何内容。
以下是一个演示如何使用它们的示例。
NavigableMap<Integer, String> map = new TreeMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.put(4, "four");
map.put(5, "five");
map.keySet().forEach(key -> System.out.print(key + " "));
System.out.println();
NavigableSet<Integer> descendingKeys = map.descendingKeySet();
descendingKeys.forEach(key -> System.out.print(key + " "));
运行此代码将打印出以下结果。
1 2 3 4 5
5 4 3 2 1
获取子映射视图
最后一组方法使您可以访问映射部分的视图。
subMap(fromKey, fromInclusive, toKey, toInclusive)
:返回一个子映射,您可以在其中决定是否包含边界。headMap(toKey, inclusive)
:头部映射也是如此。tailMap(fromKey, inclusive)
:尾部映射也是如此。
这些映射是此映射的视图,您可以通过删除或添加键值对来更新它们。不过,添加元素有一个限制:您不能添加超出视图创建边界之外的键。
上次更新: 2021 年 9 月 14 日