按嵌套列表元素对列表进行分组

3

我有一个带有以下参数的Car对象:

private String model;
private BigDecimal price;
private Color color;
private BigDecimal milleage;
private List<String> components;

我创建了一个Car对象列表:

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")));

现在我想创建一个Map<String, List<Car>>,其中字符串是组件列表的元素,List<Car>是包含此组件的Car对象的列表。
我尝试了一些类似问题的解决方法,但真的不知道如何解决这个问题。
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)));
}
1个回答

2
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())));

只要您使用的是或更高版本,就可以在中使用Collectors#flatMapping将整个流简化为一个收集器:
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()))));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接