>) 使用 lambdas/streams,arraylist,lambda,java-8,hashmap,java-stream"/>

首页 > 解决方案 > 如何将嵌套的对象列表转换为地图(地图>) 使用 lambdas/streams

问题描述

我正在使用两个 for 循环将以下对象结构列表转换为 HashMap,如下所示。

public class Vehical {

    private Category category;
    private List<Brand> brandList;

    public Category getCategory() {
        return category;
    }

    public List<Brand> getBrandList() {
        return brandList;
    }
}

public class Category {

    private Integer catId;

    public Integer getCatId() {
        return catId;
    }       
}

public class Brand {

    private Model model;

    public Model getModel() {
        return model;
    }
}

public class Model {

    private List<Reg> regList;

    public List<Reg> getRegList() {
        return regList;
    }

}

public class Reg {

    private Integer regId;

    public Integer getRegId() {
        return regId;
    }
}

public static void main(String[] args) {

    //Assume that filled with data.*** 
    List<Vehical> vehicalList = getVehicals();

    Map<Integer, Map<Integer, Brand>> vehicalMap = new HashMap<Integer, Map<Integer, Brand>>();

    for (Vehical vehical : vehicalList) {

        Map<Integer, Brand> brandMap = new HashMap<Integer, Brand>();

        for (Brand brand : vehical.getBrandList()) {
            //Assume that zeroth index is always available and getting "RegId" from the zeroth element is fixed.***
            brandMap.put(brand.getModel().getRegList().get(0).getRegId(), brand);
        }
        vehicalMap.put(vehical.getCategory().getCatId(), brandMap);
    }

}

如何使用 lambdas/streams 做同样的事情?我尝试使用 flatMap,但它没有用。流式传输时无法访问嵌套的 RegId。

此外,我尝试使用 forEach,但最后它看起来像相同的 for 循环解决方案。

Map<Integer, Map<Integer, Brand>> vehicalMap = new HashMap<>();

vehicalList.forEach(v -> {
    Map<Integer, Brand> brandMap = new HashMap<>();
    v.getBrandList().stream().forEach(b -> brandMap
            .put(b.getModel().getRegList().get(0).getRegId(), b));

    vehicalMap.put(v.getCategory().getCatId(), brandMap);
});

任何帮助,将不胜感激。

更新基于@Nidhish Krishnan 答案的 工作代码示例

标签: arraylistlambdajava-8hashmapjava-stream

解决方案


试试这个

解决方案 1

如果你想得到基于分组的结果,试试这个

Map<Integer, Map<Integer, Brand>> vehicalMap = getVehicals().stream()
    .collect(Collectors.groupingBy(vechiles -> vechiles.getCategory().getCatId(),
        Collectors.collectingAndThen(
                Collectors.groupingBy(vechile -> vechile.getBrandList().get(0).getModel().getRegList().get(0).getRegId()),
                e ->e.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, v -> v.getValue().get(0).getBrandList().get(0)))
        )
    ))
    .entrySet().stream()
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

解决方案 2

如果您不想使用分组,请尝试以下一种

Map<Integer, Map<Integer, Brand>> vehicalMap = getVehicals().stream()
    .collect(Collectors.toMap(
        vechile -> vechile.getCategory().getCatId(),
        vechile -> vechile.getBrandList().stream()
                .collect(Collectors.toMap(
                        brands -> brands.getModel().getRegList().get(0).getRegId(), 
                        brand -> brand, (a, b) -> b)), 
        (a, b) -> a));

更新 1

不知道你有什么数据vehicalList,这就是我创建测试的方式vehicalList

private static List<Vehical> getVehicals() {
    return Lists.newArrayList(
        new Vehical(new Category(21), Lists.newArrayList(new Brand(new Model(Lists.newArrayList(new Reg(100), new Reg(101), new Reg(102)))))),
        new Vehical(new Category(22), Lists.newArrayList(new Brand(new Model(Lists.newArrayList(new Reg(200), new Reg(201), new Reg(202)))))),
        new Vehical(new Category(23), Lists.newArrayList(new Brand(new Model(Lists.newArrayList(new Reg(300), new Reg(301), new Reg(302)))))),
        new Vehical(new Category(24), Lists.newArrayList(new Brand(new Model(Lists.newArrayList(new Reg(400), new Reg(401), new Reg(402)))))),
        new Vehical(new Category(25), Lists.newArrayList(new Brand(new Model(Lists.newArrayList(new Reg(500), new Reg(501), new Reg(502)))))),
        new Vehical(new Category(26), Lists.newArrayList(new Brand(new Model(Lists.newArrayList(new Reg(600), new Reg(601), new Reg(602)))))),
        new Vehical(new Category(26), Lists.newArrayList(new Brand(new Model(Lists.newArrayList(new Reg(700), new Reg(701), new Reg(702))))))
    );
}

推荐阅读