Предположим, у меня есть группа автомобилей-бамперов, у которых есть размер, цвет и идентификатор ("код автомобиля") по бокам.
class BumperCar {
int size;
String color;
String carCode;
}
Теперь мне нужно сопоставить автомобили-бамперы со 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 ])
]
Я попробовал следующее, что на самом деле делает то, что я хочу. Но проблема в том, что он материализует немедленный результат (в 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
Конечно, если это возможно.
Обратите внимание, что для краткости я опустил геттеры и конструкторы. Вы также можете предположить, что методы equals
и hashCode
реализованы правильно. Также обратите внимание, что я использую SizeColorCombination
который я использую в качестве группового ключа. Этот класс, очевидно, содержит свойства size
и color
. Также могут использоваться классы, такие как Tuple
или Pair
или любой другой класс, представляющий комбинацию двух произвольных значений.
Изменить: Также обратите внимание, что вместо цикла можно использовать старый цикл for, но это не входит в сферу этого вопроса.