如何使用Java流和reduce()来获取Map的键和值的计算总和?

huangapple go评论123阅读模式
英文:

How to use Java streams and reduce() to get the sum of calculations with the key and value of the Map?

问题

I'll try to keep it as brief as possible.

我会尽量保持简洁。

I have this map: Map<Neuron, Float> connections. It contains a Neuron-Object as Key and the weight of the connection as value.

我有这个映射:Map<Neuron, Float> connections。它包含一个 Neuron 对象作为键,连接的权重作为值。

The Neuron class has a method "getOutput" to get the output-Value of the neuron.

Neuron 类有一个方法 "getOutput" 用于获取神经元的输出值。

What I want to do is to go over every neuron in the map, calculate neuron.getOutput * connections.get(neuron) and sum all of that into one variable together.

我想要做的是遍历映射中的每个神经元,计算 neuron.getOutput * connections.get(neuron),然后将所有结果相加到一个变量中。

Is there an elegant way to do this with Java-Streams? Maybe with reduce? I tried it but couldn't get it to work properly.

是否有一种优雅的方法可以使用 Java-Streams 来实现这个?也许可以使用 reduce 吗?我尝试过但无法使其正常工作。

inputConnections.keySet().stream().reduce(
    0f,
    (accumulatedFloat, inputNeuron) -> accumulatedFloat + inputNeurons.get(inputNeuron) * inputNeuron.getOutput(),
    Float::sum
);

I guess the 0f results in everything getting multiplied with 0.

我猜想这里的 0f 导致了所有的结果都被乘以 0。

This code seems to work, but I'd like a more elegant solution.

这段代码似乎可以工作,但我想要一个更加优雅的解决方案。

AtomicReference<Float> tmp = new AtomicReference<>(0f);
inputConnections.keySet().forEach(inputNeuron -> {
    tmp.updateAndGet(v -> v + inputNeuron.getOutput() * inputConnections.get(inputNeuron));
});

这是您的翻译部分。如果您需要进一步的帮助,请随时提问。

英文:

I'll try to keep it as brief as possible.

I hava this map: Map<Neuron,Float> connections. It contains a Neuron-Objekt as Key and the weight of the connection as value.

The Neuron class has a method "getOutput" to get the output-Value of the neuron.

What I want to do is to go over every neuron in the map, calculate neuron.getOutput * connections.get(neuron) and sum all of that into one variable together.

Is there an elegant way to do this with Java-Streams? Maybe with reduce? I tried it but couldn't get it to work properly.

inputConnections.keySet().stream().reduce(
            0f,
            (accumulatedFloat, inputNeuron) -&gt; accumulatedFloat + inputConnections.get(inputNeuron),
            Float::sum);

I guess the 0f results in everything getting multiplied with 0.

This code seems to work, but I'd like a more elegant solution.

AtomicReference&lt;Float&gt; tmp = new AtomicReference&lt;&gt;(0f);
    inputConnections.keySet().forEach(inputNeuron -&gt; {
        tmp.updateAndGet(v -&gt; new Float((float) (v + inputNeuron.getOutput() * inputConnections.get(inputNeuron))));
    });

答案1

得分: 4

你也可以使用mapsum来实现相同的功能。

inputConnections.entrySet().stream().mapToDouble(entry -> entry.getKey().getOutput() * entry.getValue()).sum()
英文:

you can also achieve the same with map and sum

inputConnections.entrySet().stream().mapToDouble(entry -&gt; entry.getKey().getOutput() * entry.getValue()).sum()

答案2

得分: 3

你使用reduce的方法几乎正确。它应该看起来像第二个代码片段,其中你将神经元的output与地图中的值(inputConnections.get(..))相乘。

inputConnections.entrySet()
        .stream()
        .reduce(0f,
                (result, entry) -> result + entry.getKey().getOutput() * entry.getValue(),
                Float::sum);
英文:

Your approach using reduce is (almost) correct. It should look like the second code snippet where you multiply the neuron's output with the value from the map (inputConnections.get(..))

inputConnections.entrySet()
        .stream()
        .reduce(0f,
                (result, entry) -&gt; result + entry.getKey().getOutput() * entry.getValue(),
                Float::sum);

答案3

得分: 0

你也可以使用并行流(注意:仅在处理大型数据集时才有意义)。如果你需要一些额外的统计信息,除了sum之外,收集器summarizingDouble会很有帮助:

DoubleSummaryStatistics sumStat = connections.entrySet().parallelStream()
        .map(entry -> Double.valueOf(entry.getKey().getOutput() * entry.getValue()))
        .collect(Collectors.summarizingDouble(Double::doubleValue));
System.out.println(sumStat);

示例输出:
DoubleSummaryStatistics{count=3, sum=18.000000, min=4.000000, average=6.000000, max=8.000000}

以下是一个较短的版本(感谢Rob的评论):

sumStat = connections.entrySet().parallelStream()
        .mapToDouble(entry -> entry.getKey().getOutput() * entry.getValue())
        .summaryStatistics();
英文:

You can also use parallel streams (be careful: only makes sense with huge datasets). In case you need some statistics additional to the sum, the collector summarizingDouble is helpful:

DoubleSummaryStatistics sumStat = connections.entrySet().parallelStream()
                .map(entry -&gt; Double.valueOf(entry.getKey().getOutput() * entry.getValue()))
                .collect(Collectors.summarizingDouble(Double::doubleValue));
System.out.println(sumStat);

Example output:
DoubleSummaryStatistics{count=3, sum=18.000000, min=4.000000, average=6.000000, max=8.000000}

Here is a shorter version (thank you Rob for your comment):

sumStat = connections.entrySet().parallelStream()
        .mapToDouble(entry -&gt; entry.getKey().getOutput() * entry.getValue())
        .summaryStatistics();

huangapple
  • 本文由 发表于 2023年1月6日 12:58:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75027081.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定