Map接口包含一个称为Map.Entry的公共、静态、内部接口,该接口表示键值对。 Map.entrySet方法返回一组Map.Entry元素。 在Java 8之前,给map排序时主要使用接口中的getKey和getValue方法。 Java8 中,增加了下表中的静态方法。
方法 |
描述 |
comparingByKey(Comparator<? super K> cmp) |
Returns a comparator that comparesMap.Entryby key using the givenComparator |
comparingByValue() |
Returns a comparator that comparesMap.Entryin natural order on value |
comparingByValue(Comparator<?superV>cmp) |
ReturnsacomparatorthatcomparesMap.Entryby value using the givenComparator |
下面用计算字典中单词长度和数量映射,来说明怎么使用这些方法。 Unix系统在/usr/share/dict/words
目录中包含一个文件,保存了Webster第二版词典的内容。 我们用 Files.lines方法读取文件行并生成包含这些行的字符串流。
System.out.println("\nNumber of words of each length:");
try (Stream<String> lines = Files.lines(dictionary)) {
lines.filter(s -> s.length() > 20)
.collect(Collectors.groupingBy(
String::length, Collectors.counting()))
.forEach((len, num) -> System.out.printf("%d: %d%n", len, num));
} catch (IOException e) {
e.printStackTrace();
}
简要解释一下:
- 使用 try-with-resources 块中在读取文件, Stream实现了 Auto Closeable,因此在try块退出时,Java会在Stream上调用close方法,然后在File上调用close方法。
- filter 将处理范围限制为仅长度为20个字符以上的单词。
- Collectors的groupingBy方法将Function作为第一个参数,表示分类器。在这里,分类器是每个字符串的长度。如果仅提供一个参数,则结果将一个Map,其中键是分类器的值,而值是与分类器匹配的元素的列表。groupingBy(String::length)会生成Map >,其中键是单词长度,值是该长度单词的列表。
- 接受两个参数的 groupingBy ,可以提供另一个收集器(称为下游收集器),对单词列表进行后处理。返回类型为Map,其中键是单词长度,值是字典中该长度的单词数。
输出结果为:
Number of words of each length:
21: 82
22: 41
23: 17
24: 5
长度为21的字符的单词有82个,依次类推。 这个例子以map中单词长度的升序打印。 可以使用 Map.Entry.comparingByKey 来实现降序排列。
System.out.println("\nNumber of words of each length (desc order):");
try (Stream<String> lines = Files.lines(dictionary)) {
Map<Integer, Long> map = lines.filter(s -> s.length() > 20).collect(Collectors.groupingBy(
String::length, Collectors.counting()));
map.entrySet().stream().sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
.forEach(e -> System.out.printf("Length %d: %2d words%n", e.getKey(), e.getValue()));
} catch (IOException e) {
e.printStackTrace();
}
在计算Map 之后,提取entrySet并生成一个流。 Stream 上的 sorted 接受比较器,生成排序后的流。Map.Entry.comparingByKey接受一比较器(指定倒序),生成一个按键排序的比较器,
程序输出为:
Number of words of each length (desc order):
Length 24: 5 words
Length 23: 17 words
Length 22: 41 words
Length 21: 82 words
评论