如何基于特定字段流式传输和收集多个最大项目


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

最新更新