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);
如何流式传输和收集到一张以颜色为关键和值的地图上,该地图上有按品牌排列的最旧汽车列表?最终的地图应该有
{
"red": [
{
"make": "Honda",
"year": "1998"
},
{
"make": "Audi",
"year": "2022"
}
],
"blue": [
{
"make": "Toyota",
"year": "2007"
}
]
}
一旦groupingBy被用于根据颜色进行分组,就有问题将列表(值(减少到最旧的汽车,然后收集到整个地图。
能够通过获得预期结果
Map<String, Map<String, Optional<Car>>> carMap =
carList.stream().collect(Collectors.groupingBy(Car::getColor,
Collectors.groupingBy(Car::getMake,
Collectors.minBy(Comparator.comparing(Car::getYear)))));
{红色={奥迪=可选[轿车(品牌=奥迪,年份=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));