如何在Java中根据对象的属性将对象列表分组为Map of Map?

w80xi6nr  于 2023-05-27  发布在  Java
关注(0)|答案(3)|浏览(152)

我有一个对象列表,我想转换为Map的Map。

class A {
  String aProp;
  String bProp;
  String cProp;
}

我有List<A> aList。我试着把它们转换成Map

Map<aProp, Map<bProp, cProp>>

我怎样才能做到这一点?我尝试了Collectors.groupingBy,但仍然无法实现我想要的。

tquggr8v

tquggr8v1#

假设aPropbProp的组合是唯一的:

Map<String, Map<String, String>> map = aList.stream()
        .collect(Collectors.groupingBy(
                a -> a.aProp,
                Collectors.toMap(a -> a.bProp, a -> a.cProp)
        ));
// map ==> {1={2=3}, 2={3=4}, 3={4=5}}

如果aPropbProp的示例具有相同的值,则toMap收集器将引发异常。如果发生这种情况,您可以使用其他toMap方法之一。例如,toMap(a -> a.bProp, a -> a.cProp, (x, y) -> y))将采用最后一个值(尽管顺序并不能保证“最后一个值”是什么)。

7lrncoxx

7lrncoxx2#

您可以在List<A>上创建一个for循环,为每次迭代添加一个新的map条目。

Map<String, Map<String, String>> map(List<A> aList) {
    Map<String, Map<String, String>> map = new HashMap<>();
    for (A a : aList) map.put(a.aProp, Map.of(a.bProp, a.cProp));
    return map;
}

示例输出

{a={b=c}, d={e=f}, g={h=i}, j={k=l}}
goucqfw6

goucqfw63#

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;
    }

    public String getaProp() {
        return aProp;
    }

    public String getbProp() {
        return bProp;
    }

    public String getcProp() {
        return cProp;
    }

}

List<A> listOfA = List.of(new A("r", "b", "c"), new A("r", "b", "d"),
          new A("t", "b", "e"), new A("t", "c", "f"),
          new A("r", "d", "g"), new A("w", "b", "j"));

这是你要的东西。

Map<String, Map<String, String>> map = new HashMap<>();

for (A a : listOfA) {
    map.computeIfAbsent(a.getaProp(), v -> new HashMap<>())
    .put(a.getbProp(), a.getcProp());
}

map.entrySet().forEach(System.out::println);
System.out.println();

印刷品

r={b=d, d=g}
t={b=e, c=f}
w={b=j}

请注意,由于A的示例具有重复的aProp'sbProp's,因此遇到的下一个示例替换了前一个示例。在前面的示例中,b,d for r替换了b,c for r
为了防止这种情况,如果需要,您可以创建一个ArrayList<String>作为内部Map的值。

Map<String, Map<String, List<String>>> map2 = new HashMap<>();
for (A a : listOfA) { 
     map2.computeIfAbsent(a.getaProp(), v -> new HashMap<>())
         .computeIfAbsent(a.getbProp(), v -> new ArrayList<>())
             .add(a.getcProp());
}

map2.entrySet().forEach(System.out::println);

印刷品

r={b=[c, d], d=[g]}
t={b=[e], c=[f]}
w={b=[j]}

在这个例子中,c被保留在ArrayList中。

相关问题