如何使用Java 8 Streams对By对象属性进行分组并映射到另一个对象?
2022-09-02 13:57:01
假设我有一组保险杠汽车,它们的侧面有尺寸,颜色和标识符(“汽车代码”)。
class BumperCar {
int size;
String color;
String carCode;
}
现在,我需要将保险杠汽车映射到一个对象,每个对象都包含属性 ,以及汽车代码的a。List
DistGroup
size
color
List
class DistGroup {
int size;
Color color;
List<String> carCodes;
void addCarCodes(List<String> carCodes) {
this.carCodes.addAll(carCodes);
}
}
例如
[
BumperCar(size=3, color=yellow, carCode=Q4M),
BumperCar(size=3, color=yellow, carCode=T5A),
BumperCar(size=3, color=red, carCode=6NR)
]
应导致:
[
DistGroup(size=3, color=yellow, carCodes=[ Q4M, T5A ]),
DistGroup(size=3, color=red, carCodes=[ 6NR ])
]
我尝试了以下方法,这实际上做了我想要它做的事情。但问题是,它将中间结果具体化(变成一个),我也认为它可以立即完成(也许使用or或或什么),从而产生更优雅的代码。Map
mapping
collectingAndThen
reducing
List<BumperCar> bumperCars = …;
Map<SizeColorCombination, List<BumperCar>> map = bumperCars.stream()
.collect(groupingBy(t -> new SizeColorCombination(t.getSize(), t.getColor())));
List<DistGroup> distGroups = map.entrySet().stream()
.map(t -> {
DistGroup d = new DistGroup(t.getKey().getSize(), t.getKey().getColor());
d.addCarCodes(t.getValue().stream()
.map(BumperCar::getCarCode)
.collect(toList()));
return d;
})
.collect(toList());
如何在不使用变量作为中间结果的情况下获得所需的结果?
编辑:如何在不实现中间结果的情况下获得所需的结果?我只是在寻找一种不会实现中间结果的方法,至少在表面上不是这样。这意味着我不喜欢使用这样的东西:
something.stream()
.collect(…) // Materializing
.stream()
.collect(…); // Materializing second time
当然,如果可能的话。
请注意,为了简洁起见,我省略了 getter 和构造函数。您还可以假定 equals
和 hashCode
方法已正确实现。另请注意,我使用的是 SizeColorCombination
,我将其用作分组依据键。此类显然包含属性大小
和颜色
。也可以使用元组
,Pair
,Entry
或任何其他表示两个任意值组合的类。
编辑:还要注意,当然,可以使用ol'skool for loop代替,但这不在本问题的范围之内。