Java 集合:SortedMap 接口

Java 的SortedMap接口(全限定名:java.util.SortedMap)是java.util.Map接口的子接口,它在Map的基础上增加了一个核心特性:存储在SortedMap中的元素会在内部自动排序。这一特性使得我们可以按照预设的排序顺序,直接迭代SortedMap中存储的元素,无需额外手动处理排序逻辑。

  

SortedMap 的实现 TreeMap

Java 默认提供了 SortedMap 接口的内置实现,名为 TreeMap(java.util.TreeMap)。

创建一个TreeMap

你通过其构造函数实例化一个 TreeMap 实例。例如:

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

还可以将 Comparator 实现传递给 TreeMap 构造函数。然后,该 Comparator 将用于对存储在 SortedMap 中的键值对的键进行排序。例如:

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

  

SortedMap 排序

Java 中 SortedMap 的排序顺序有两种确定方式:

(1)一是采用元素自身的自然排序(前提是元素实现了 java.lang.Comparable 接口);

(2)二是由你为 SortedMap 提供的 Comparator 来指定。

默认情况下,元素按升序迭代,从 “最小” 元素开始,依次到 “最大” 元素结束。不过,也可以通过 TreeMap.descendingKeySet () 方法按降序迭代元素。例如:

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

map.put("id", "1000");
map.put("name", "Helen");
map.put("age", "33");
map.put("email", "helen@outlook.com");

for(Map.Entry<String,String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + "=" + entry.getValue());
}

运行结果:

name=Helen
id=1000
email=helen@outlook.com
age=33

  

SortedMap 迭代

迭代 SortedMap 就像迭代普通的 Map 一样。由于 SortedMap 的键是经过排序的,你很可能希望按照键的排序顺序来迭代它们。迭代 SortedMap 的键可以通过调用其 keySet() 方法,例如:

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

map.put("id", "1000");
map.put("name", "Helen");
map.put("age", "33");
map.put("email", "helen@outlook.com");

// 迭代键
for(String key : map.keySet()) {
    System.out.println(key);
}

System.out.println("===============================");

// 迭代值
for (String value : map.values()) {
    System.out.println(value);
}

System.out.println("===============================");

// 迭代条目
for(Map.Entry<String,String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + "=" + entry.getValue());
}

运行结果:

name
id
email
age
===============================
Helen
1000
helen@outlook.com
33
===============================
name=Helen
id=1000
email=helen@outlook.com
age=33

获取所使用的比较器

如果你的 SortedMap 是使用 Comparator 创建的,你可以通过 SortedMap 的 comparator() 方法获取所使用的 Comparator。例如:

Comparator comparator = sortedMap.comparator();

 

获取第一个键

SortedMap 接口提供了一个便捷方法 firstKey (),用于获取其键集中的第一个(即最小的)键。例如:

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

map.put("id", "1000");
map.put("name", "Helen");
map.put("age", "33");
map.put("email", "helen@outlook.com");

String firstKey = map.firstKey();
System.out.println(firstKey); // name

  

获取最后一个键

SortedMap 接口还提供了一个便捷方法 lastKey(),专门用于获取其键集中的最后一个(即最大的)键。例如:

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

map.put("id", "1000");
map.put("name", "Helen");
map.put("age", "33");
map.put("email", "helen@outlook.com");

String lastKey = map.lastKey();
System.out.println(lastKey); // age

 

头部映射

SortedMap 接口提供了一个名为 headMap() 的方法,该方法会返回一个新的 Map,其中包含原 SortedMap 中按既定排序顺序排列的前部分元素。headMap () 方法需要接收一个参数作为分隔界限,用于确定哪些元素会被包含在返回的子映射中 —— 所有键小于(或按排序规则早于)该参数的元素都会被纳入其中。例如:

SortedMap<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<String,String> subMap = map.headMap("b");
System.out.println(subMap); //{d=4000, c=3000}

subMap.put("d", "40"); // 会影响 map 引用的 Map 实例
System.out.println(map); //{d=40, c=3000, b=2000, a=1000}

返回的头部映射将包含键值对("d","4000")和("c","3000"),因为在此 SortedMap 使用的排序顺序中,键 "d" 和 "c" 小于/早于 "b"。

注意,子 Map 是 Map 的一个视图,如果对子 Map 进行操作,会影响到 Map。上面代码中,使用 subMap 修改键“d”的值为“40”,主 map 的值也被修改了。

  

尾部映射

SortedMap 接口提供了一个名为 tailMap () 的方法,该方法会返回一个新的 Map,其中包含原 SortedMap 中按按既定排序顺序排列的后部分元素。tailMap () 方法需要接收一个参数作为分隔界限,用于确定哪些元素会被包含在返回的子映射中 —— 所有键等于或大于(或按排序规则不早于)该参数的元素都会被纳入其中。例如:

SortedMap<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<String,String> subMap = map.tailMap("b");
System.out.println(subMap); //{b=2000, a=1000}

subMap.put("a", "10"); // 会影响 map 引用的 Map 实例
System.out.println(map); //{d=4000, c=3000, b=2000, a=10}

返回的尾部映射将包含键值对("b","2000")、("a","1000"),因为 "b"、"a" 大于或等于传递给tailMap() 的参数 "b"。

  

子映射

SortedMap 接口还提供了 subMap() 方法,该方法能返回一个新的 Map,即原 SortedMap 的子映射。subMap() 方法接收两个参数作为边界条件,用于界定子映射所包含的元素范围 —— 子映射将包含所有键大于或等于第一个参数,且同时小于第二个参数的元素。例如:

SortedMap<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<String,String> subMap = map.subMap("c", "a");
System.out.println(subMap); //{c=3000, b=2000}

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

返回的子映射将包含键值对("c","3000")、("b","2000"),因为键 "c"、"b" 都大于或等于 "c",且小于 "a"。

更多信息查看 https://docs.oracle.com/javase/8/docs/api/java/util/SortedMap.html API 文档。

  

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