नेस्टेड सूची के तत्वों द्वारा समूह सूची [डुप्लिकेट]

Jan 25 2021

मुझे कार ऑब्जेक्ट मिला है जैसे पैरामीटर:

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

मैंने कार वस्तुओं की सूची बनाई:

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

जवाब

2 NikolasCharalambidis Jan 25 2021 at 19:15

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

जब तक आप जावा -10 या उसके बाद का उपयोग करते हैं, तब तक आप java-9Collectors#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()))));