1

Lets assume I have a list of walls listOfWalls and that each wall object has following hierarchy:

wall -> wallType -> wallEntry(list of wall materials ) -> wallMaterial -> wallMaterialType(enum type), 

so in order to get wallMaterialType of some wall in this list, I would go like

wall.getWallType().getWallEntry().getWallMaterial().getWallMaterialType();

Now class Wall has also following params: width and height which multiplied together gets an area of the wall by calling my function getWallArea() from Wall class.

What I would like to achieve is to get area of all wallMaterialTypes from a list of walls calculated, so for instance lets assume we have 2 walls:

  1. Wall 1 with following wallMaterialTypes: Brick, Plaster, Wood and wallArea() of 35 sq. meters.
  2. Wall 2 with following wallMaterialTypes: Hay, Plaster and wallArea() of 105 square meters.

Now what output I would like to have is:

BRICK: 35 square meters.
Plaster: 140 square meters.
Wood: 35 square meters.
Hay: 105 square meters.

My code so far is looking something like this where have I pulled for each

 Map<WallType, Double> getIt = listOfWalls.stream()
                .collect(groupingBy(Wall::getWallType, Collectors.summingDouble(Wall::getWallArea)));

From there I am clueless how to go? Help appreciated.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
joyag95613
  • 13
  • 3

1 Answers1

2

It seems you want to map by the WallMaterialType enum.

Map<WallMaterialType, Double> result = walls.stream()
            .flatMap(wall -> wall.getWallType().getWallEntry().getWallMaterials()
                    .stream()
                    .map(wallMaterial -> new AbstractMap.SimpleEntry<>(wallMaterial.getWallMaterialType(),
                            wall.getWallArea())))
            .collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey,
                    Collectors.summingDouble(AbstractMap.SimpleEntry::getValue)));

If you keep calling map(..) and reach the WallMaterials, you would lose the Wall's wallArea Hence, I have grouped everything into a single flatMap step to return a map (simple pair would do too) of wall material type and the wall's area.

(The flatMap step returns a simple mapping of a WallMaterialType and the wallArea to which the wallMaterialType belongs to).

The collect is similar to what you've already written.

Thiyagu
  • 17,362
  • 5
  • 42
  • 79
  • nitpick - `wall.getWallType().getWallEntry().stream()` should be sufficient given `wallEntry` is a list of wall material. – Naman Apr 02 '20 at 13:37
  • @user7 I have written edit to your answer for possible further clarification and solution. – joyag95613 Apr 02 '20 at 18:23