有没有一种干净(且空安全)的方法来乘以Java中的映射值?

2022-08-31 22:21:16

我有一个,并且想要将映射中的所有值乘以2,但将nulls保留为null。Map<String, Double>

我显然可以使用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)
        }

    }
}

此外,有时 返回的映射是不可变的映射,因此无法使用 到位完成此操作。我无法想出一个更干净的流解决方案。someMapFunctionMap.replaceAll


答案 1

我的第一个直觉是建议一个输入,它将值映射到新值并以 .StreamMapentrySetcollectors.toMap()

遗憾的是,当值映射器函数返回 时,将引发 。因此,它不适用于输入的值。Collectors.toMapNullPointerExceptionnullnullMap

作为替代方案,由于您无法更改输入,我建议您创建它的副本,然后调用:MapreplaceAll

Map<String, Double> adjustedMap = new HashMap<>(someMap);
adjustedMap.replaceAll ((k,v) -> v != null ? 2*v : null);

答案 2

作为流媒体和/或复制解决方案的替代方案,Google Guava 中存在 Maps.transformValues() 实用程序方法:

Map<String, Double> adjustedMap = Maps.transformValues(someMap, value -> (value != null) ? (2 * value) : null);

这将返回原始映射的惰性视图,该视图本身不执行任何工作,但在需要时应用给定函数。这可以是专业人士(如果您不太可能需要所有值,这将为您节省一些计算时间)和缺点(如果您多次需要相同的值,或者如果您需要在不看到更改的情况下进一步更改),具体取决于您的使用情况。someMapadjustedMap


推荐