Iterating a list inside a map of map using java 8 streams

Viewed 3263

I have a map that contains date as key and (another map of string as key and list as the value) as value. Map<LocalDate, Map<String, List<FlexiServer>>>, I want to populate another map that has String as a key and double as a value. The contents of FlexiServer are

public class FlexiServer {
    private String serverNumber;
    private Double quantity;
    private Integer level;
    private String parentServer;
}

So, basically I want to iterate from first the exterior map to get the internal map and then iterate the internal map to get the list of FlexiServers and populate the new map having server number as key and list of quantities as values. How can I do this using java 8 streams?

I tried with for loop, but I will like to replace it using Java streams.

if(data.isPresent()) {
            for(Map.Entry<LocalDate, Map<String, List<FlexiServer>>> entry : data.get().entrySet()) {
                for(Map.Entry<String, List<FlexiServer>> innerEntry : entry.getValue().entrySet()) {
                    for(FlexiServer dto : innerEntry.getValue()) {
                        dailyRequirements.computeIfAbsent(dto.getserverNumber(),
                            k -> new ArrayList<>()).add(dto.getQuantity());
                    }
                }
            }
        }
2 Answers

Just get the values from the outer map and inner map and then use Collectors.groupingby

Map<String, List<Double>> result = map.values()
                                      .stream()
                                      .map(Map::values)
                                      .flatMap(Collection::stream)
                                      .flatMap(List::stream)
            .collect(Collectors.groupingBy(FlexiServer::getServerNumber, Collectors.mapping(FlexiServer::getQuantity, Collectors.toList())));

You can do it this way using Java8 StreamApi

    Map<LocalDate, Map<String, List<FlexiServer>>> localDateMapMap = new HashMap<>();
    localDateMapMap.put(LocalDate.now(), new HashMap<String, List<FlexiServer>>() {{
      put("1", new ArrayList<FlexiServer>() {{
        add(new FlexiServer() {{
          setQuantity(200D);
          setServerNumber("001");
        }});
        add(new FlexiServer() {{
          setQuantity(500D);
          setServerNumber("001");
        }});
        add(new FlexiServer() {{
          setQuantity(800D);
          setServerNumber("002");
        }});
      }});
      put("2", new ArrayList<FlexiServer>() {{
        add(new FlexiServer() {{
          setQuantity(200D);
          setServerNumber("003");
        }});
        add(new FlexiServer() {{
          setQuantity(500D);
          setServerNumber("001");
        }});
        add(new FlexiServer() {{
          setQuantity(800D);
          setServerNumber("001");
        }});
      }});
    }});
    Map<String, Double> map = new HashMap<>();
    localDateMapMap.values().stream()
        .map(Map::values)
        .flatMap(Collection::stream)
        .flatMap(Collection::stream)
        .forEach(flexiServer -> {
          if (map.containsKey(flexiServer.getServerNumber())) {
            map.replace(flexiServer.getServerNumber(),
                map.get(flexiServer.getServerNumber()) + flexiServer.getQuantity());
          } else {
            map.put(flexiServer.getServerNumber(), flexiServer.getQuantity());
          }
        });
    map.forEach((serverNumber, quantity) -> System.out
        .println("ServerNumber = " + serverNumber + "  Quantity = " + quantity));
Related