如何使用Lambda /流将对象的嵌套列表转换为地图(Map <Integer,Map <Integer,Object >>)

时间:2019-08-09 20:08:35

标签: arraylist lambda java-8 hashmap java-stream

我使用两个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);
    }

}

如何使用Lambda /流执行相同的操作? 我尝试使用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的答案来code sample工作

1 个答案:

答案 0 :(得分:1)

尝试一下

解决方案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))))))
    );
}