Java流能否合并?多流实现最长单词查找的代码合并咨询
合并Java流的方案及你的代码优化
当然可以合并Java中的流!而且合并流操作通常能减少中间集合的创建,既提升代码简洁性,又能避免不必要的内存占用,尤其是处理大数据量的时候优势更明显。
先看看你当前的代码逻辑:你先把所有子任务的单词结果收集到一个List里,然后两次遍历这个List——第一次找最长单词的长度,第二次过滤出对应长度的单词。其实我们可以把这些步骤合并成一套连续的流调用,完全不需要中间的maxLengthWords集合。
优化后的合并流代码
return ForkJoinTask.invokeAll(createSubtasks()).stream() .flatMap(task -> task.join().stream()) .collect(Collectors.groupingBy(String::length)) .entrySet() .stream() .max(Map.Entry.comparingByKey()) .map(Map.Entry::getValue) .orElse(Collections.emptyList());
代码说明
- 第一步还是和你的逻辑一致:通过
invokeAll获取所有ForkJoin子任务,然后用flatMap把每个子任务返回的单词流合并成一个全局的单词流,这里没有提前收集到List里。 - 接着用
Collectors.groupingBy(String::length)把所有单词按长度分组,得到一个Map<Integer, List<String>>——key是单词长度,value是对应长度的所有单词。 - 把Map的entrySet转成流后,用
max(Map.Entry.comparingByKey())找到键最大的条目,也就是对应最长单词长度的那一组。 - 最后取出这一组的单词列表,如果没有任何单词(比如所有子任务都返回空),就返回空列表,替代了你原来用
orElse(-1)再过滤的逻辑。
其他可选方案(按需选择)
如果你不想用分组的方式,也可以把单词先收集到一个List,再链式处理,但这种方式会两次遍历List,效率不如分组方案:
List<String> allWords = ForkJoinTask.invokeAll(createSubtasks()).stream() .flatMap(task -> task.join().stream()) .collect(Collectors.toList()); return allWords.stream() .filter(s -> s.length() == allWords.stream() .mapToInt(String::length) .max() .orElse(-1)) .collect(Collectors.toList());
内容的提问来源于stack exchange,提问作者Good York
相关产品推荐
相关产品推荐

