如何在处理后将Java Pair流映射合并为单个Pair?
解决方案
完整实现代码
import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.commons.lang3.tuple.Pair; public class StreamTeeingDemo { public static void main(String[] args) { Stream<Pair<String, Map<String, String>>> stream = Stream.of( Pair.of("fruits", Map.of("red","apple", "yellow", "banana")), Pair.of("vegetables", Map.of("red","tomato", "yellow", "corn")), Pair.of("red meat", Map.of("cow","beef", "sheep", "mutton")), Pair.of("white meat", Map.of("fish","tuna", "poultry", "chicken")) ); Pair<String, String> result = stream.collect(Collectors.teeing( // 处理Pair左侧元素,生成带括号的字符串 Collectors.collectingAndThen( Collectors.mapping(Pair::getLeft, Collectors.joining(", ")), joined -> String.format("(%s)", joined) ), // 处理Pair右侧元素,生成完整描述句子 Collectors.collectingAndThen( Collectors.flatMapping( pair -> pair.getRight().entrySet().stream() .map(entry -> formatEntry(entry, pair.getLeft())), Collectors.joining(", ") ), joined -> String.format("%s are all very nutritious for the human body!", joined) ), Pair::of )); // 输出结果 System.out.println(result.getLeft()); System.out.println(result.getRight()); } // 根据类别格式化Map条目为目标字符串 private static String formatEntry(Map.Entry<String, String> entry, String category) { String key = entry.getKey(); String value = entry.getValue(); if ("fruits".equals(category) || "vegetables".equals(category)) { // 颜色类条目:首字母大写,值转复数 String capitalizedKey = key.substring(0, 1).toUpperCase() + key.substring(1); String pluralValue = getPluralForm(value); return String.format("%s %s", capitalizedKey, pluralValue); } else { // 肉类条目:直接拼接,值转复数 String pluralValue = getPluralForm(value); return String.format("%s %s", key, pluralValue); } } // 简单处理英文复数(可根据实际需求扩展) private static String getPluralForm(String word) { if (word.endsWith("o")) { return word + "es"; } else if (word.endsWith("y") && !word.matches(".*[aeiou]y$")) { return word.substring(0, word.length() - 1) + "ies"; } else { return word + "s"; } } }
关键逻辑说明
第一个收集器:
- 通过
mapping(Pair::getLeft, Collectors.joining(", "))提取所有Pair的左值,拼接成逗号分隔的字符串。 - 再用
collectingAndThen将结果包裹在括号中,得到(fruits, vegetables, red meat, white meat)。
- 通过
第二个收集器:
- 用
flatMapping遍历每个Pair的右值(Map),将每个键值对通过formatEntry转换成符合要求的描述片段(比如red+apple→Red apples)。 - 把所有片段用逗号拼接后,再通过
collectingAndThen添加固定结尾,生成完整句子。
- 用
Teeing收集器:
同时执行上述两个收集逻辑,最后将两个结果通过Pair::of组合成最终的Pair<String, String>。
该实现未使用分组操作和谓词,完全符合需求。
内容的提问来源于stack exchange,提问作者yaserso
相关产品推荐
相关产品推荐

