I have a List<POJO>
that I want to extract data from and the variables I'm interested in are:
Environment: String
Application: String
Throughput: Double
There are 7 Environment
objects and each Environment
has 18 Application
objects, which each have multiple values
.
I'm trying to iterate over the List<POJO>
and store these values in a Hashmap<Environment.ToString, Hashmap<Applications.ToString, List<Double>>
I'm trying to use Java 8's Lambda features; my code so far:
private HashMap<String, List<BigDecimal>> appMap = new HashMap<String, List<BigDecimal>>();
private HashMap<String, HashMap> envMap = new HashMap<String, HashMap>();
for(POJO chartModel: List<POJO>) {
appMap.computeIfAbsent(chartModel.getName(), v -> new ArrayList<BigDecimal>())
.add(BigDecimal.valueOf(chartModel.getThroughput()));
envMap.put(chartModel.getEnvironment(), appMap);
}
Firstly, is there a shorthand way to iterate over the List
inside the inner Map
using Java8
?
Secondly, my code isn't quite right, so currently the map adds all the Throughput
values to its Application
key, so I end up with 18 keys with a list of values.
What I need it to do is in my envMap
I should have 7 Environment
objects, with each having its 18 Application
objects and values, so there would be 126 Application
objects in total. Can this be achieved the way I'm attempting it, is there a Lambda way to achieve this?
You need to use 2 grouping by operations: the first one groups according to the environment and the second one groups according to the name. Finally, you need to map each values to the BigDecimal
value of their throughput.
Assuming pojo
is a List<POJO>
:
Map<String, Map<String, List<BigDecimal>>> result =
pojo.stream()
.collect(Collectors.groupingBy(
POJO::getEnvironment,
Collectors.groupingBy(
POJO::getName,
Collectors.mapping(p -> BigDecimal.valueOf(p.getThroughput()), Collectors.toList())
)
));
You are creating only one Map
, appMap
, which you are putting into envMap
for every key. You obviously want to create a new Map
for each distinct key and you already know the right tool, computeIfAbsent
. But you should also mind the “diamond operator”. While not being a new Java 8 feature, your code will clearly benefit from removing the repetitions of the type parameters. Putting it all together, the operation will look like:
HashMap<String, Map<String, List<BigDecimal>>> envMap = new HashMap<>();
for(POJO chartModel: list) {
envMap.computeIfAbsent(chartModel.getEnvironment(), env -> new HashMap<>())
.computeIfAbsent(chartModel.getName(), name -> new ArrayList<>())
.add(BigDecimal.valueOf(chartModel.getThroughput()));
}
You can also express the same logic using the Stream API, as shown by Tunaki, but you don’t need to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With