当前位置: 首页 > 知识库问答 >
问题:

如何使用lambdas/streams将嵌套的对象列表转换为映射(map)

邵骁
2023-03-14

我正在使用两个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做同样的事情呢?我试过用平面地图,但没用。流式传输时无法访问嵌套得注册区域.

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答案更新工作代码示例

共有1个答案

鲜于致远
2023-03-14

试试这个

如果你想根据分组得到结果,试试这个

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

如果您不想使用分组,请尝试下面的分组

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

不确定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))))))
    );
}
 类似资料:
  • 首先,我有下面的发票清单。每个列表对象都有一个零件号、一个描述、数量和一个价格。 我将其映射到数量上,并将其排序到数量上,得到以下结果: 但是我如何在上进行映射,以便在我的结果中显示在所显示的数量前面?我不能这样做:

  • 当我试图使用ModelMapper将嵌套的java对象转换为嵌套的DTO时,我遇到了一个问题。在父DTO对象中,子DTO为null。以下是代码片段。 实体类: DTO的课程: 这是映射器代码: 输出: 输出用户DTO:UserDTO[名称=xyz,地址=null,产品=null] 在这里,我想将用户实体转换为UserDTO-dto。我得到了地址和产品DTO的空值。我在这里到底缺少什么?有人知道吗?

  • 我不确定如何将嵌套的结果集映射到域实体中。 以下是我想做的事情的大概想法: 2张桌子 域实体(包含嵌套列表) LoanEntity.java Book.java 持久实体 Loans.java Dao.xml(不知道如何映射它,尝试使用一个) 注意:此查询将复制找到的#本书的记录。 LoanMapper.java 下面的错误是我得到的: 错误:结果类型中的未知属性“books.bookName”c

  • 在索引位置1的输入中遇到的字符串的前半部分将被替换为字符“-”使用流我们如何执行操作? 我有上面的列表,我想用我这样做的循环将每个嵌套列表值的第一个位置替换为“-” 样本输出:[[0,-],[6,-],[0,-],[6,gh],[4,ij],[0,ab],[6,cd]] 但是任何人都可以解释如何使用流来实现同样的目标

  • 我有下面的pojo 此employee类用于从mybatis orm获取对象列表(list)。 mybatis将输出作为列表返回,因为mybatis不支持将Map作为返回类型 我必须把它转换成地图 我尝试了下面的方法,但没有成功,因为它需要getName()和getId()方法 请告知是否有一种方法可以在不修改员工pojo的情况下使用stream实现。 注意:我知道我们可以使用ofr或for ea

  • 我如何在下面的场景中使用Mapstruct进行bean映射。 现在我想把sourceId映射到targetId,courseName映射到subjectName,studentName映射到memberName(list到list)。