【问题标题】:Java Stream Api - good ways to operate on Map<String, Double>?Java Stream Api - 操作 Map<String, Double> 的好方法?
【发布时间】:2015-12-28 22:33:59
【问题描述】:

我想用加权平均值进行一些计算。有两张地图

Map<String, Double> weightedVector;
Map<String, Double> otherVector;

伪算法是这样的

foreach entry in weightedVector:
  get same entry from otherVector 
  - if it exists then multiply weights and add new entry to another map
  - otherwise do nothing

我想利用 Stream API 并想出了这个

Stream<Double> map = weightedVector.entrySet().parallelStream()
.map(entry -> {
    Double t = otherVector.get(entry.getKey());
    Double v = entry.getValue();
    return (t != null && v != null) 
            ? t * v 
            : 0.0;
});

我问自己一个问题,使用旧样式访问otherVector 是否是一种好习惯,就像上面的 sn-p 一样。

对我来说主要问题是我有两个输入映射,并且想要获得相同类型的输出映射,但上面的代码从计算中得到了 StreamDouble

我最好使用stream().collect(..),然后如何?

最好不要使用HashMap,而是创建一个包含键值对的容器对象并改用它?

【问题讨论】:

  • 那么,当在另一个地图中没有找到任何条目时(如您的描述所述),您想什么都不做,还是要存储 0.0(如您的代码所示)?

标签: java java-8 java-stream collect


【解决方案1】:

假设在没有对应条目的情况下,你实际上什么都不想做:

Map<String, Double> result = 
        weightedVector.entrySet()
                      .stream()
                      .filter(e -> otherVector.containsKey(e.getKey()))
                      .collect(Collectors.toMap(
                          Map.Entry::getKey,
                          e -> e.getValue() * otherVector.get(e.getKey())));

【讨论】:

    【解决方案2】:

    如果您可以就地修改映射,那么您还可以遍历 otherVector 条目并相应地更新 weightedVector 映射:

    otherVector.forEach((key, t) -> weightedVector.computeIfPresent(key, (k, v) -> t * v));
    

    这将计算otherVector 中每个键的otherVectorweightedVector 值的乘积。

    【讨论】:

    • 感谢您指出这一点,这对于大型向量来说是一个很好的解决方案,在这种情况下,一直复制内存可能需要权衡取舍。
    猜你喜欢
    • 2014-08-15
    • 1970-01-01
    • 2022-12-05
    • 2019-08-10
    • 2014-05-27
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    相关资源
    最近更新 更多