Java Streams:使用groupingBy时如何排序列表元素及确定Map值类型
Java groupingBy收集器:列表排序与类型优化方案
原代码
Stream<String> stream = Stream.of("lions", "tigers", "bears", "toads", "tarantullas"); Map<Integer, ?> map7 = stream.collect( Collectors.groupingBy( String::length, Collectors.mapping(s -> s.charAt(0), Collectors.toList() ) )); System.out.println("map7: " + map7); System.out.println("value type: " + map7.get(5).getClass());
原输出
map7: {5=[l, b, t], 6=[t], 11=[t]} value type: java.util.ArrayList
问题解答
1. 对每个列表中的字母排序
有两种实用实现方式:
方式一:兼容Java 8及以上版本(用collectingAndThen)
在mapping收集器的下游,通过collectingAndThen先收集为列表,再执行排序逻辑:
Stream<String> stream = Stream.of("lions", "tigers", "bears", "toads", "tarantullas"); Map<Integer, List<Character>> map = stream.collect( Collectors.groupingBy( String::length, Collectors.mapping( s -> s.charAt(0), Collectors.collectingAndThen( Collectors.toList(), list -> { list.sort(Comparator.naturalOrder()); return list; } ) ) ));
方式二:Java 12+版本(用toSortedList)
Java 12新增的toSortedList收集器可直接生成已排序的列表,代码更简洁:
Stream<String> stream = Stream.of("lions", "tigers", "bears", "toads", "tarantullas"); Map<Integer, List<Character>> map = stream.collect( Collectors.groupingBy( String::length, Collectors.mapping( s -> s.charAt(0), Collectors.toSortedList() ) ));
两种方式运行后的输出结果(已排序):
map: {5=[b, l, t], 6=[t], 11=[t]}
2. Map的合适类型
原代码中Map<Integer, ?>使用通配符类型,会导致后续操作需强制转换,类型安全性差。推荐使用Map<Integer, List<Character>>:
- 键类型
Integer对应字符串长度,类型明确 - 值类型
List<Character>对应分组后的首字母列表,完全匹配收集的元素类型
使用明确类型后,代码的可读性、安全性都会提升,无需处理通配符带来的类型不确定问题。
内容的提问来源于stack exchange,提问作者march_in
相关产品推荐
相关产品推荐

