-1

I'm have the following objects:

 List<CartItem> cartItemsList = cart.getItems().stream()
                .sorted(Comparator.comparingDouble(f -> f.getProduct().getPrice()))
                .collect(Collectors.toList());

 Map<Product, Map<Customization, List<CartItem>>> map =cartItemsList.stream()
                .collect(Collectors.groupingBy(CartItem::getProduct,
                        Collectors.groupingBy(CartItem::getCustomizations)));

My issue is about map: because I need to preserve order, defined in the first list(cartItemsList) , map isn't a good solution. Have I to use linkedHashMap(or any other solution) to preserve order and how do that?

Fidelis
  • 91
  • 1
  • 11
  • 2
    Does this help you? https://stackoverflow.com/questions/29090277/how-do-i-keep-the-iteration-order-of-a-list-when-using-collections-tomap-on-a – Madlemon Mar 23 '21 at 15:22
  • If you need a `Map` that preserves elements in insertion order, then yes, `LinkedHashMap` is a good choice. – Jesper Mar 23 '21 at 15:32
  • 1
    Yes, `Collectors.groupingBy` has an overloaded version with [`Supplier`](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#groupingBy-java.util.function.Function-java.util.function.Supplier-java.util.stream.Collector-) parameter – Nowhere Man Mar 23 '21 at 15:33
  • @Madlemon maybe..how apply this example to my scenario? – Fidelis Mar 23 '21 at 15:33
  • e.g. `.collect(LinkedHashMap::new,(map, cartItem) -> map.put(cartItem.getProduct(), cartItem.getCustomizations()), Map::putAll);` – Madlemon Mar 23 '21 at 15:46

1 Answers1

1

As mentioned in javadoc, the Supplier<Map> goes after classifier.

 Map<Product, Map<Customization, List<CartItem>>> map = cartItemsList.stream()
    .collect(Collectors.groupingBy(
        CartItem::getProduct, 
        LinkedHashMap::new,
        Collectors.groupingBy(CartItem::getCustomizations)
));

If the nested map needs to be LinkedHashMap too, the following code should be used:

Map<Product, Map<Customization, List<CartItem>>> map = cartItemsList.stream()
    .collect(Collectors.groupingBy(
        CartItem::getProduct, 
        LinkedHashMap::new,
        Collectors.groupingBy(
            CartItem::getCustomizations,
            LinkedHashMap::new,
            Collectors.toList()
        )
));

For Collectors.toMap it is also possible to provide specific Map using 4-argument overload, where Supplier<Map> goes last argument.

Nowhere Man
  • 19,170
  • 9
  • 17
  • 42