Предположим, у меня есть группа бамперных машинок, на боках которых есть размер, цвет и идентификатор (код машины).
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. , но это выходит за рамки данного вопроса.
groupingBy()
по умолчанию группирует значения вList
, поэтомуtoList()
можно опустить. - person Lino   schedule 18.01.2019