I would like to map an NxN array into a Map in Java 8.
The idea is that every [i][0] element is a key and every [i][j] with j>0 is a list of values for every key in the map.
Thanks for any help. :)
This is my class:
public class GroupingDishes {
    public static void main(String[] args) {
        String[][] dishes = {
                {"Salad", "Tomato", "Cucumber", "Salad", "Sauce"},
                {"Pizza", "Tomato", "Sausage", "Sauce", "Dough"},
                {"Quesadilla", "Chicken", "Cheese", "Sauce"},
                {"Sandwich", "Salad", "Bread", "Tomato", "Cheese"}
        };
        Map<String, HashSet<String>> groupDishes = groupingDishes(dishes);
    }
    public static Map<String, HashSet<String>> groupingDishes(String[][] dishes) {
        Map<String, HashSet<String>> mapFood = new HashMap<>();
        for (int i = 0; i < dishes.length; i++) {
            String food = dishes[i][0];
            for (int j = 0; j < dishes[i].length; j++) {
                if (mapFood.containsKey(food)) {
                    HashSet<String> existingIngredients = mapFood.get(dishes[i][0]);
                    existingIngredients.add(dishes[i][j]);
                    mapFood.put(food, existingIngredients);
                } else {
                    HashSet<String> newIngredient = new HashSet<>();
                    mapFood.put(food, newIngredient);
                }
            }
        }
        return mapFood;
    }
}
                You could convert String[][] to a stream of String[],
then collect to a map,
using the first item of the String[] as the key,
and the rest as the values of the set.
public static Map<String, HashSet<String>> groupingDishes2(String[][] dishes) {
    return Arrays.stream(dishes)
        .collect(Collectors.toMap(
            arr -> arr[0],
            arr -> Arrays.stream(arr).skip(1).collect(Collectors.toCollection(HashSet::new))));
}
Btw, I doubt you really need a Map<String, HashSet<String>>.
It would be better to change the types to Map<String, Set<String>>,
and then the implementation can be written simpler too.
public static Map<String, Set<String>> groupingDishes(String[][] dishes) {
    return Arrays.stream(dishes)
        .collect(Collectors.toMap(
            arr -> arr[0],
            arr -> Arrays.stream(arr).skip(1).collect(Collectors.toSet())));
}
Or even better, as @Holger suggested, an even better alternative, because "streams with skip and limit do not perform very well, also Collectors do not get any hint for the result's initial capacity":
public static Map<String, Set<String>> groupingDishes(String[][] dishes) {
    return Arrays.stream(dishes)
        .collect(Collectors.toMap(
            arr -> arr[0],
            arr -> new HashSet<>(Arrays.asList(arr).subList(1, arr.length))));
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With