Java 集合:NavigableMap 类

Java 的NavigableMap接口(全限定名:java.util.NavigableMap)是SortedMap接口的子接口。它在SortedMap的基础上扩展了一系列实用方法,能够更便捷地对映射中存储的键和值进行 “导航” 操作(例如精准查找、范围定位等)。

  

NavigableMap 的实现类

作为一个接口,NavigableMap 本身无法直接实例化,在使用 NavigableMap 前,你需要借助它的具体实现类。在 java.util 包中,NavigableMap 接口仅有一个核心实现类 —— java.util.TreeMap。此外,java.util.concurrent 包中也存在 NavigableMap 的实现类,但该内容不在本教程的讨论范围内。

  

创建一个 NavigableMap

要创建一个 NavigableMap,你必须创建实现了 NavigableMap 接口的某个类的实例。例如:

NavigableMap<String,String> navigableMap = new TreeMap<>();

除了默认构造方法,你还可以向 TreeMap 构造函数传递一个 Comparator 实现。然后,这个 Comparator 将用于对存储在 NavigableMap 中的键值对的键进行排序。例如:

Comparator<String> comparator = new MyComparatorImpl<String>();
SortedMap<String,String> sortedMap = new TreeMap<>(comparator);

  

descendingKeySet()

NavigableMap 中第一个实用的导航方法是 descendingKeySet()。该方法会返回一个 NavigableSet,其中元素的排列顺序与原始键集恰好相反。值得注意的是,返回的这个 “视图” 由原始 NavigableMap 的键集提供底层支持,因此对降序键集所做的修改会自动同步到原始集合中。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");

System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}
System.out.println(map.descendingKeySet()); //[a, b, c, d]

  

descendingMap()

第二种实用的导航方法是 descendingMap()。该方法会返回一个 NavigableMap 对象,作为原始映射的反向视图 —— 视图中元素的排列顺序与原始映射完全相反。由于这是原始映射的视图,因此对该视图所做的任何修改都会自动同步到原始映射中。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

NavigableMap<String,String> reversMap = map.descendingMap();
System.out.println(reversMap); //{a=1000, b=2000, c=3000, d=4000}

  

headMap()

headMap() 方法会返回原始 NavigableMap 的一个视图,该视图仅包含“小于”给定元素的元素。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

SortedMap<String,String> headmap1 = map.headMap("b");
System.out.println(headmap1); //{d=4000, c=3000}

// inclusive=true
NavigableMap<String,String> headmap2 = map.headMap("b", true);
System.out.println(headmap2); //{d=4000, c=3000, b=2000}

  

tailMap()

tailMap() 方法与 headMap() 方法类似,不同之处在于 tailMap() 会返回所有等于或高于给定参数元素的元素。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

SortedMap<String,String> tailMap = map.tailMap("b");
System.out.println(tailMap); //{b=2000, a=1000}

tailMap 变量将引用一个 SortedMap,其中包含来自 NavigableMap 中键为 "b" 和 "a" 的所有键值对,因为这些键被视为等于或大于传递给 tailMap() 方法的参数值 "b"。

  

subMap()

subMap() 允许你传递两个参数来划定要返回的视图映射的边界。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

// 获取位于 [c, b) 的条目
SortedMap<String,String> submap1  = map.subMap("c", "b");
System.out.println(submap1); //{c=3000}

// fromInclusive=true 且 toInclusive=true,因此
// 获取位于 [c, d] 的条目
NavigableMap<String,String> submap2 = map.subMap("c", true, "b", true);
System.out.println(submap2); //{c=3000, b=2000}

  

ceilingKey()

ceilingKey() 方法返回此映射中大于或等于传递给 ceilingKey() 方法的参数元素的最小键。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

String ceilingKey  = map.ceilingKey("c");
System.out.println(ceilingKey); //c

  

floorKey()

floorKey() 方法与 ceilingKey() 方法的作用相反。因此,floorKey() 会返回小于或等于传递给 ceilingKey()的参数值的最大键。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

String floorKey  = map.floorKey("c");
System.out.println(floorKey); //c

  

higherKey()

higherKey() 方法会返回此映射中大于(不等于)传递给 higherKey() 方法的参数的最小元素。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

String higherKey = map.higherKey("c");
System.out.println(higherKey); //b

  

lowerKey()

lowerKey() 方法与 higherKey() 方法的作用相反。因此,lowerKey() 会返回小于传递给 lowerKey() 方法的参数值的最大键。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

String lowerKey = map.lowerKey("c");
System.out.println(lowerKey); //d

  

ceilingEntry()

ceilingEntry() 方法返回 NavigableMap 中不小于(大于或等于)传递给 ceilingEntry() 方法的参数值的最小键所存储的键+值。因此,ceilingEntry() 与 ceilingKey() 方法类似,不同之处在于 ceilingKey() 方法只返回键,而 ceilingEntry() 返回一个包含键和值的 Map.Entry 对象。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

Map.Entry<String,String> ceilingEntry = map.ceilingEntry("c");
System.out.println(ceilingEntry); //c=3000

  

floorEntry()

floorEntry() 方法的作用与 ceilingEntry() 方法相反。floorEntry() 方法会返回键值对,其中的键是小于或等于传递给 floorEntry() 方法的参数值的最大键。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

Map.Entry<String,String> floorEntry = map.floorEntry("c");
System.out.println(floorEntry); //c=3000

  

higherEntry()

higherEntry() 方法返回为大于传递给 higherEntry() 方法的参数值的最小键所存储的键+值。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

Map.Entry<String,String> higherEntry = map.higherEntry("c");
System.out.println(higherEntry); //b=2000

  

lowerEntry()

lowerEntry() 方法会返回一个键值对,其中包含的键是所有小于传递给该方法参数值的键中最大的那个。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

Map.Entry<String,String> lowerEntry = map.lowerEntry("c");
System.out.println(lowerEntry); //d=4000

  

pollFirstEntry()

pollFirstEntry() 方法会返回并移除 NavigableMap 中的“第一个”条目(键+值),如果映射为空,则返回 null。“第一个”指的是根据键的排序顺序确定的最小元素。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

Map.Entry<String,String> pollFirstEntry = map.pollFirstEntry();
System.out.println(pollFirstEntry); //d=4000

  

pollLastEntry()

pollLastEntry() 方法会返回并移除映射中的“最后一个”元素,如果映射为空,则返回 null。“最后一个”指的是根据映射的元素排序顺序确定的最大键。例如:

NavigableMap<String,String> map = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);
    }
});

map.put("a", "1000");
map.put("b", "2000");
map.put("c", "3000");
map.put("d", "4000");
System.out.println(map); //{d=4000, c=3000, b=2000, a=1000}

Map.Entry<String,String> pollLastEntry = map.pollLastEntry();
System.out.println(pollLastEntry); //a=1000

更多信息参考 https://docs.oracle.com/javase/8/docs/api/java/util/NavigableMap.html API 文档。

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号