Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested for each loop returning map with Java 8 streams

I just started with Java 8 and streams, and not able to find out how to write this code in Java 8:

Map<Integer, CarShop> result = new HashMap<>();     
for (Car car : someListOfCars) {
    List<CarProduct> listOfCarProducts = car.getCarProducts();
    for (CarProduct product : listOfCarProducts) {
        result.put(product.getId(), car.getCarShop());
    }
}

Any help?

like image 649
Coder07 Avatar asked Jun 12 '15 21:06

Coder07


1 Answers

You can often convert your iterative solution directly to a stream by using .collect:

Map<Integer, CarShop> result = someListOfCars.stream().collect(
        HashMap::new,
        (map, car) -> car.getCarProducts().forEach(
                prod -> map.put(prod.getId(), car.getCarShop())
        ),
        Map::putAll
);

You can make the solution more flexible at the cost of additional allocations:

Map<Integer, CarShop> result = someListOfCars.stream()
        .flatMap(car -> car.getCarProducts().stream()
                .map(prod -> new SimpleImmutableEntry<>(prod.getId(), car.getCarShop()))
        ).collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> b));

This will allow you to collect any way you wish. For example, you would be able to remove (a,b)->b to force an exception if there are duplicate ids instead of silently overwriting the entry.

like image 148
Misha Avatar answered Nov 29 '22 13:11

Misha