arraylist - 如何将嵌套的对象列表转换为地图(地图>) 使用 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 答案的 工作代码示例
解决方案
试试这个
解决方案 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))))))
);
}
推荐阅读
- qt - 如何从命令行选择 VLC QT 接口配置文件
- python - 在 Keras 中集成多个模型预测触发回溯警告
- db2 - SQL 错误:
在使用它的上下文中无效。如何在 DB2 数据库的持久性文件中设置 maxColumnNameLength 属性? - swift - 从每米秒数快速获取每公里分钟数
- r - 将几行空行添加到 R 中的数据框中的最优雅方法?
- python - Python生成器让我困惑
- c# - 命名txt文件
- java - 嵌入式模式下的 Apache Drill sqlline 在 Ubuntu 18.04 上崩溃
- java - 关于 Java 中带有 System.out.print 的运算符的问题
- javascript - 如何将 className 添加到自定义组件的包装器中