我有一个Map<String, Double>
,并希望将映射中的所有值乘以2,但将空值保留为空值。
我显然可以使用for循环来做这件事,但我想知道是否有更干净的方法来做这件事?
Map<String, Double> someMap = someMapFunction();
Map<String, Double> adjustedMap = new Hashmap<>();
if (someMap != null) {
for (Map.Entry<String,Double> pair : someMap.entryset()) {
if (pair.getValue() == null) {
adjustedMap.put(pair.getKey(), pair.getValue());
} else {
adjustedMap.put(pair.getKey(), pair.getValue()*2)
}
}
}
此外,有时someMapFunction
返回的映射是不可变的映射,因此无法使用Map.replaceAll
就地完成此操作。我想不出一个更干净的流解决方案。
发布于 2018-10-17 16:16:02
我的第一个直觉是建议输入Map
的entrySet
的Stream
,它将值映射到新值,并以collectors.toMap()
结束。
不幸的是,当值映射器函数返回null
时,Collectors.toMap
抛出NullPointerException
。因此,它不适用于输入Map
的null
值。
作为另一种选择,由于您不能改变输入Map
,因此我建议您创建它的副本,然后调用replaceAll
Map<String, Double> adjustedMap = new HashMap<>(someMap);
adjustedMap.replaceAll ((k,v) -> v != null ? 2*v : null);
发布于 2018-10-17 16:38:09
作为流式传输和/或复制解决方案的替代方案,Google Guava中存在Maps.transformValues()
实用程序方法
Map<String, Double> adjustedMap = Maps.transformValues(someMap, value -> (value != null) ? (2 * value) : null);
这将返回原始map的惰性视图,该视图本身不做任何工作,但在需要时应用给定的函数。这可以是一个优势(如果你不太可能需要所有的值,这将为你节省一些计算时间)和一个劣势(如果你需要多次相同的值,或者如果你需要在adjustedMap
看不到变化的情况下进一步更改someMap
),这取决于你的使用情况。
发布于 2018-10-17 16:21:09
可以这样做。
someMap.entrySet().stream()
.filter(stringDoubleEntry -> stringDoubleEntry.getValue() != null) //filter null values out
.forEach(stringDoubleEntry -> stringDoubleEntry.setValue(stringDoubleEntry.getValue() * 2)); //multiply values which are not null
如果您需要第二个映射,其中的值不为空,只需使用forEach
将它们放入新映射中。
https://stackoverflow.com/questions/52850108
复制相似问题