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.

5
  • Does getWallMaterialType return a List<WallMaterialType>? Commented Apr 2, 2020 at 12:51
  • 2
    Sharing some classes would help to try and not write your code by ourelves ;) Commented Apr 2, 2020 at 12:53
  • 1
    Please always try to provide a minimal reproducible example Commented Apr 2, 2020 at 12:54
  • 1
    As far as I see you have the correct map. Do you ask how to print it in this format? Or how to print it within the stream pipeline? Commented Apr 2, 2020 at 12:55
  • Related of mostly a duplicate of Stream groupingBy a list of enum types Commented Apr 2, 2020 at 14:16

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

nitpick - wall.getWallType().getWallEntry().stream() should be sufficient given wallEntry is a list of wall material.
@user7 I have written edit to your answer for possible further clarification and solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.