Home > Mobile >  How to iterate Multilevel Map using Java 8 stream?
How to iterate Multilevel Map using Java 8 stream?

Time:11-08

I'm good with Java streams, so maybe this is not the minimal solution, but here's what I came up with using streams to get what I think you want:

Do we have DishDiet as a POJO and DishDietTest as the main class? I am getting data as desired but how to loop it? How to iterate Multilevel Map using Java 8 stream? How to get print based on classification done using stream?

public class DishDiet {

    private final String name;
    private final boolean vegetarian;
    private final int calories;
    private final Type type;
    private final CaloricLevel caloricLevel;

    public DishDiet(String name, boolean vegetarian, int calories, Type type, CaloricLevel caloricLevel) {
        this.name = name;
        this.vegetarian = vegetarian;
        this.calories = calories;
        this.type = type;
        this.caloricLevel = caloricLevel;
    }

    public String getName() {
        return name;
    }

    public boolean isVegetarian() {
        return vegetarian;
    }

    public int getCalories() {
        return calories;
    }

    public Type getType() {
        return type;
    }

    public CaloricLevel getCaloricLevel() {
        return caloricLevel;
    }

    @Override
    public String toString() {
        return name;
    }

    
    public enum Type {
        MEAT, FISH, OTHER
    }

    public enum CaloricLevel {
        DIET, NORMAL, FAT
    }

}
public class DishDietTest {

    private static List<DishDiet> getAllDishDiet() {
        return Arrays.asList(new DishDiet("pork", false, 800, DishDiet.Type.MEAT, DishDiet.CaloricLevel.FAT),
                new DishDiet("beef", false, 700, DishDiet.Type.MEAT, DishDiet.CaloricLevel.FAT),
                new DishDiet("chicken", false, 400, DishDiet.Type.MEAT, DishDiet.CaloricLevel.DIET),
                new DishDiet("french fries", true, 530, DishDiet.Type.OTHER, DishDiet.CaloricLevel.NORMAL),
                new DishDiet("rice", true, 350, DishDiet.Type.OTHER, DishDiet.CaloricLevel.DIET),
                new DishDiet("season fruit", true, 120, DishDiet.Type.OTHER, DishDiet.CaloricLevel.DIET),
                new DishDiet("pizza", true, 550, DishDiet.Type.OTHER, DishDiet.CaloricLevel.NORMAL),
                new DishDiet("prawns", false, 300, DishDiet.Type.FISH, DishDiet.CaloricLevel.DIET),
                new DishDiet("salmon", false, 450, DishDiet.Type.FISH, DishDiet.CaloricLevel.NORMAL));
    }

    public static void main(String[] args) {

        Map<DishDiet.Type, Map<DishDiet.CaloricLevel, List<DishDiet>>> dishesByTypeCaloricLevel = getAllDishDiet()
                .stream().collect(groupingBy(DishDiet::getType, groupingBy((dish -> {
                    if (dish.getCalories() <= 400)
                        return DishDiet.CaloricLevel.DIET;
                    else if (dish.getCalories() <= 700)
                        return DishDiet.CaloricLevel.NORMAL;
                    else
                        return DishDiet.CaloricLevel.FAT;
                }

        ))));

        System.out.println(dishesByTypeCaloricLevel);

    }

}

CodePudding user response:

Do you mean like this?

    dishesByTypeCaloricLevel.forEach((type, innerMap) 
            -> {
                System.out.println(type);
                innerMap.forEach((cl, list)
                        -> {
                            System.out.println("    "   cl);
                            list.forEach(dd -> System.out.println("        "   dd));
                        });
            });

Output:

OTHER
    NORMAL
        french fries
        pizza
    DIET
        rice
        season fruit
FISH
    NORMAL
        salmon
    DIET
        prawns
MEAT
    FAT
        pork
    NORMAL
        beef
    DIET
        chicken

I am not using streams for iterating and printing. I recommend that we just use the forEach methods of Map and List. The use is similar but a bit simpler.

Do we have DishDiet as a POJO and DishDietTest as the main class? …

Yes, that’s fine.

CodePudding user response:

for(Map.Entry<DishDiet.Type, Map<DishDiet.CaloricLevel,List<DishDiet>>> t : dishesByTypeCaloricLevel.entrySet()){
    DishDiet.Type key = t.getKey();
    for (Map.Entry<DishDiet.CaloricLevel,List<DishDiet>> e : 
        t.getValue().entrySet())
        System.out.println("OuterKey:"   key   " InnerKey: "   e.getKey()  " VALUE:"  e.getValue());
}
  • Related