如何按相同前缀分组HashMap中键对应的列表值?
问题修正与实现方案
你需要把原Map中键前缀相同的条目分组,合并对应List的值生成新Map,但当前代码存在几个明显问题:
- 返回类型是
Set<String>,和你需要的Map<String, List>完全不符 - 代码只能针对单个指定前缀做筛选,没法自动识别所有前缀并分组
- 完全没做List内容的合并操作
下面是两种可行的实现方式:
Java 9+ 版本(简洁版)
利用Java 9新增的flatMapping可以直接完成分组+列表合并:
import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class PrefixGrouping { public static <T> Map<String, List<T>> groupByPrefix(Map<String, List<T>> inputMap) { return inputMap.entrySet().stream() // 提取键的前缀:按.分割取第一部分,注意转义正则中的. .collect(Collectors.groupingBy( entry -> entry.getKey().split("\\.")[0], // 把所有对应列表的元素扁平合并成一个新列表 Collectors.flatMapping(entry -> entry.getValue().stream(), Collectors.toList()) )); } }
Java 8 兼容版本
如果还在用Java 8,因为没有flatMapping,可以先分组得到嵌套列表,再手动扁平化:
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class PrefixGrouping { public static <T> Map<String, List<T>> groupByPrefix(Map<String, List<T>> inputMap) { // 先按前缀分组,得到Map<String, List<List<T>>> Map<String, List<List<T>>> grouped = inputMap.entrySet().stream() .collect(Collectors.groupingBy( entry -> entry.getKey().split("\\.")[0], Collectors.mapping(Map.Entry::getValue, Collectors.toList()) )); // 把嵌套列表扁平化为单层列表 return grouped.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, entry -> { List<T> merged = new ArrayList<>(); entry.getValue().forEach(merged::addAll); return merged; } )); } }
关键说明
split("\\.")[0]:通过.分割键字符串,取第一部分作为分组前缀(.在正则表达式里是通配符,必须用\\转义)- 泛型
<T>的使用让方法支持任意类型的List元素,不用局限于Object
测试示例
假设输入:
Map<String, List<String>> input = new HashMap<>(); input.put("a.1", List.of("l1-1", "l1-2")); input.put("a.2", List.of("l2-1")); input.put("b.1", List.of("l3-1")); input.put("b.2", List.of("l4-1", "l4-2"));
调用groupByPrefix(input)后,输出结果为:
{a=[l1-1, l1-2, l2-1], b=[l3-1, l4-1, l4-2]}
内容的提问来源于stack exchange,提问作者user1167753
相关产品推荐
相关产品推荐

