如何按长度对String流进行映射分组?
按字符串长度分组String流的正确实现
嘿,你遇到的问题其实是对Stream特性不熟悉导致的——Stream确实只能被消费一次,而且手动循环遍历长度的方式既麻烦又没必要,用Java Stream内置的收集器就能完美解决这个需求!
先说说原代码的问题
- Stream是一次性消费的:一旦你调用了
filter这类终端操作,流就被关闭了,没法再重复使用; - 你没法提前知道最长字符串的长度,循环遍历i的方式根本不现实,还容易漏分组。
正确的实现方式
直接用Collectors.groupingBy就能一步完成按长度分组,而且可以指定分组后的值为Set(自动去重):
Stream<String> s = Stream.of("aaaa", "a", "aaa", "a", "aaaa", "aa", "aaaaaa", "aa"); Map<Integer, Set<String>> result = s.collect(Collectors.groupingBy( String::length, // 以字符串长度作为分组的Key Collectors.toSet() // 每个Key对应的Value是去重后的Set集合 ));
代码解释
Collectors.groupingBy是专门用于分组的收集器,第一个参数是分类函数,这里用方法引用String::length,表示把每个字符串的长度作为分组的键;- 第二个参数是下游收集器,这里用
Collectors.toSet(),表示把相同长度的字符串收集到Set中(自动去重,正好符合你要的Map<Integer, Set<String>>类型); - 如果不需要去重,只想保留所有相同长度的字符串,把
Collectors.toSet()换成Collectors.toList()即可。
这样写既简洁又符合Stream的设计理念,完全不需要手动处理循环或者流的重复操作问题~
内容的提问来源于stack exchange,提问作者Buzzet
相关产品推荐
相关产品推荐

