List<Car> carList = new ArrayList<>();
Car car = new Car();
car.setMake("Honda");
car.setYear(1998);
car.setColor("red");
carList.add(car);
car = new Car();
car.setMake("Honda");
car.setYear(2020);
car.setColor("red");
carList.add(car);
car = new Car();
car.setMake("Audi");
car.setYear(2022);
car.setColor("red");
carList.add(car);
car = new Car();
car.setMake("Toyota");
car.setYear(2021);
car.setColor("blue");
carList.add(car);
car = new Car();
car.setMake("Toyota");
car.setYear(2007);
car.setColor("blue");
carList.add(car);
如何将颜色作为键和值的地图流式传输和收集到具有由make创建的最旧汽车的汽车列表?最终的地图应该有
{
"red": [
{
"make": "Honda",
"year": "1998"
},
{
"make": "Audi",
"year": "2022"
}
],
"blue": [
{
"make": "Toyota",
"year": "2007"
}
]
}
一旦groupingBy用于基于颜色进行分组,通过make将列表(值)减少到最旧的汽车,然后收集到整个地图。
能够得到预期的结果
Map<String, Map<String, Optional<Car>>> carMap =
carList.stream().collect(Collectors.groupingBy(Car::getColor,
Collectors.groupingBy(Car::getMake,
Collectors.minBy(Comparator.comparing(Car::getYear)))));
{red={奥迪=可选[汽车(品牌=奥迪,年份=2022,颜色=红色)],本田=可选[汽车(品牌=本田,年份=1998,颜色=红色)]},蓝色={丰田=可选[汽车(品牌=丰田,年份=2007,颜色=蓝色)]}}
但无法将嵌套映射中的值平面映射到父映射中的汽车列表。
基本上,您应该只需要映射收集的值:
cars.stream().collect(Collectors.groupingBy(Car::color,
Collectors.collectingAndThen(
Collectors.groupingBy(Car::make,
Collectors.collectingAndThen(
Collectors.minBy(Comparator.comparing(Car::year)), Optional::get)
), map -> new ArrayList<>(map.values()))));
但实际上,这就是流变得不可读的地方…
更新
至少用更易读的方式来写:
Collector<Car, ?, Car> eldest = Collectors.collectingAndThen(
Collectors.minBy(Comparator.comparing(Car::year)),
Optional::get);
Collector<Car, ?, List<Car>> eldestByMake = Collectors.collectingAndThen(
Collectors.groupingBy(Car::make, eldest),
map -> new ArrayList<>(map.values()));
cars.stream().collect(Collectors.groupingBy(Car::color, eldestByMake));