Java中如何根据对象属性将对象列表分组为嵌套Map?
将List转换为嵌套Map的解决方案
要把List<A>转换为Map<String, Map<String, String>>(即外层key为aProp,内层key为bProp、value为cProp的嵌套Map),可以结合Collectors.groupingBy和Collectors.toMap来实现,具体代码如下:
1. 补全A类的定义(需包含getter方法)
class A { private String aProp; private String bProp; private String cProp; // 构造器 public A(String aProp, String bProp, String cProp) { this.aProp = aProp; this.bProp = bProp; this.cProp = cProp; } // 属性的getter方法 public String getaProp() { return aProp; } public String getbProp() { return bProp; } public String getcProp() { return cProp; } }
2. 转换为嵌套Map的核心代码
import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Demo { public static void main(String[] args) { // 示例数据 List<A> aList = List.of( new A("a1", "b1", "c1"), new A("a1", "b2", "c2"), new A("a2", "b1", "c3"), new A("a2", "b3", "c4") ); // 执行转换 Map<String, Map<String, String>> nestedMap = aList.stream() .collect(Collectors.groupingBy( A::getaProp, // 外层Map的key:aProp的值 // 下游收集器:将分组后的List<A>转为内层Map Collectors.toMap( A::getbProp, // 内层Map的key:bProp的值 A::getcProp, // 内层Map的value:cProp的值 // 处理同一aProp下重复bProp的冲突,示例保留原有值 (existingVal, newVal) -> existingVal ) )); // 验证输出 nestedMap.forEach((aKey, innerMap) -> { System.out.println("aProp: " + aKey); innerMap.forEach((bKey, cVal) -> System.out.printf(" bProp: %s, cProp: %s%n", bKey, cVal)); }); } }
关键逻辑说明
Collectors.groupingBy(A::getaProp):先按aProp对列表元素分组,得到Map<String, List<A>>结构。Collectors.toMap(...):作为groupingBy的下游收集器,将每个分组内的List<A>转换为内层Map,其中:- 第一个参数指定内层Map的key为
bProp; - 第二个参数指定内层Map的value为
cProp; - 第三个参数是冲突处理函数:当同一
aProp下出现重复的bProp时,定义如何处理(示例中保留原有值,你也可以改为newVal保留最新值,或者抛出异常)。
- 第一个参数指定内层Map的key为
注意事项
- 必须确保
A类有对应的getter方法,否则Stream无法访问属性;如果使用Java 16+的record类,可以省略getter,直接用属性名。 - 如果业务场景中不会出现同一
aProp下重复bProp的情况,可以省略冲突处理函数,此时若出现重复会抛出IllegalStateException。
内容的提问来源于stack exchange,提问作者Pratik
相关产品推荐
相关产品推荐

