Suppose I have a group of bumper cars, which have a size, a color and an identifier ("car code") on their sides.
class BumperCar {
int size;
String color;
String carCode;
}
Now I need to map the bumper cars to a List
of DistGroup
objects, which each contains the properties size
, color
and a List
of car codes.
class DistGroup {
int size;
Color color;
List<String> carCodes;
void addCarCodes(List<String> carCodes) {
this.carCodes.addAll(carCodes);
}
}
For example,
[
BumperCar(size=3, color=yellow, carCode=Q4M),
BumperCar(size=3, color=yellow, carCode=T5A),
BumperCar(size=3, color=red, carCode=6NR)
]
should result in:
[
DistGroup(size=3, color=yellow, carCodes=[ Q4M, T5A ]),
DistGroup(size=3, color=red, carCodes=[ 6NR ])
]
I tried the following, which actually does what I want it to do. But the problem is that it materializes the intermediate result (into a Map
) and I also think that it can be done at once (perhaps using mapping
or collectingAndThen
or reducing
or something), resulting in more elegant code.
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());
How can I get the desired result without using a variable for an intermediate result?
Edit: How can I get the desired result without materializing the intermediate result? I am merely looking for a way which does not materialize the intermediate result, at least not on the surface. That means that I prefer not to use something like this:
something.stream()
.collect(…) // Materializing
.stream()
.collect(…); // Materializing second time
Of course, if this is possible.
Note that I omitted getters and constructors for brevity. You may also assume that equals
and hashCode
methods are properly implemented. Also note that I'm using the SizeColorCombination
which I use as group-by key. This class obviously contains the properties size
and color
. Classes like Tuple
, Pair
, Entry
or any other class representing a combination of two arbitrary values may also be used.
Edit: Also note that an ol' skool for loop can be used instead, of course, but that is not in the scope of this question.