[英]Java 8 lambda adding to a list in a Hashmap, in a Hashmap
I have a List<POJO>
that I want to extract data from and the variables I'm interested in are: 我有一个List<POJO>
,我想从中提取数据,我感兴趣的变量是:
Environment: String
Application: String
Throughput: Double
There are 7 Environment
objects and each Environment
has 18 Application
objects, which each have multiple values
. 有7个Environment
对象,每个Environment
有18个Application
对象,每个对象都有多个values
。
I'm trying to iterate over the List<POJO>
and store these values in a Hashmap<Environment.ToString, Hashmap<Applications.ToString, List<Double>>
我正在尝试迭代List<POJO>
并将这些值存储在Hashmap<Environment.ToString, Hashmap<Applications.ToString, List<Double>>
I'm trying to use Java 8's Lambda features; 我正在尝试使用Java 8的Lambda功能; 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
? 首先,是否有一种使用Java8
在内部Map
内迭代List
的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. 其次,我的代码不太正确,所以当前地图将所有Throughput
值添加到其Application
键,因此我最终得到了18个带有值列表的键。
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. 我需要它做的是在我的envMap
我应该有7个Environment
对象,每个对象都有18个Application
对象和值,所以总共有126个Application
对象。 Can this be achieved the way I'm attempting it, is there a Lambda way to achieve this? 这可以通过我尝试的方式实现,是否有Lambda方法来实现这一目标?
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. 您需要按操作使用2个分组:第一个按照环境分组,第二个根据名称分组。 Finally, you need to map each values to the BigDecimal
value of their throughput. 最后,您需要将每个值映射到其吞吐量的BigDecimal
值。
Assuming pojo
is a List<POJO>
: 假设pojo
是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. 您只创建了一个Map
appMap
,您将为每个键添加到envMap
中。 You obviously want to create a new Map
for each distinct key and you already know the right tool, computeIfAbsent
. 您显然希望为每个不同的密钥创建一个新的Map
,并且您已经知道正确的工具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. 虽然不是新的Java 8功能,但您的代码显然可以从删除类型参数的重复中获益。 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. 您也可以使用Stream API表达相同的逻辑, 如Tunaki所示 ,但您不需要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.