Sorting by enum parameters items from a list using Java8 streams

joyag95613 :

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.

user7 :

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.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=401513&siteId=1