java - Group list by elements of nested list
问题描述
I have got Car object with parameters like:
private String model;
private BigDecimal price;
private Color color;
private BigDecimal milleage;
private List<String> components;
I created list of Car objects:
var cars = List.of(
Car.create("FORD", BigDecimal.valueOf(120000), Color.RED, BigDecimal.valueOf(150000),
List.of("AIR CONDITIONING", "VOICE SERVICE")),
Car.create("FORD", BigDecimal.valueOf(160000), Color.RED, BigDecimal.valueOf(150000),
List.of("AIR CONDITIONING", "VOICE SERVICE")),
Car.create("AUDI", BigDecimal.valueOf(200000), Color.BLACK, BigDecimal.valueOf(195000),
List.of("NAVIGATION", "AUTOMATIC GEARBOX")),
Car.create("FIAT", BigDecimal.valueOf(70000), Color.BLUE, BigDecimal.valueOf(85000),
List.of("AIR CONDITIONING", "MANUAL GEARBOX")));
Now I want to create Map<String, List<Car>>
where the string is element of component list and List<Car>>
is list of Car
objects which contain this component.
I tried something like this based on some similar problems but really do not know how to solve this problem:
static Map<String, List<Car>> carsThatGotComponent(List<Car> cars) {
return cars.stream()
.flatMap(car -> car.getComponents()
.stream()
.map(component -> new AbstractMap.SimpleEntry<>(car, component)))
.collect(Collectors.groupingBy(
Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Map.Entry::getValue)));
}
解决方案
Collectors#mapping
需要作为第二个参数的下游Collector
,而不是映射函数。
public static <T,U,A,R> Collector<T,?,R> mapping( Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream)
您想Collectors.toList()
改用:
return cars.stream()
.flatMap(car -> car.getComponents()
.stream()
.map(component -> new AbstractMap.SimpleEntry<>(car, component)))
.collect(Collectors.groupingBy(
AbstractMap.SimpleEntry::getValue,
Collectors.mapping(AbstractMap.SimpleEntry::getKey, Collectors.toList())));
只要您使用java-10或更高版本,您就可以使用java-9Collectors#flatMapping
将整个 Stream 简化为一个收集器:
return cars.stream()
.collect(Collectors.flatMapping(
car -> car.getComponents()
.stream()
.map(component -> new AbstractMap.SimpleEntry<>(car, component)),
Collectors.groupingBy(AbstractMap.SimpleEntry::getValue,
Collectors.mapping(AbstractMap.SimpleEntry::getKey,
Collectors.toList()))));
推荐阅读
- ios - 如何制作与文本并排的自定义垂直滑块?
- python - Python3 MRJob 输出未排序的键值对
- python-3.x - 使用 while 循环在 Python 中测试和接受用户输入
- git - 在已推送代码的 bitbucket 中的任何分支上触发 Jenkins 管道
- php - 图像干预 - 替换颜色
- javascript - 知道哪个按钮提交了表单(PHP 和 Javascript)
- swift - 如何在 Swift 中访问具有动态类型检查的属性,例如 Obj-C 的 id?
- pandas - 旋转和多索引
- python - 如何使用 Python(来自 Harvest)访问检索到的列表的元素
- ruby - 从字符串(Ruby)中提取 URL(正则表达式和链接缩短)