我如何使用Java Stream来减少此类结构?

问题描述 投票:0回答:1

这是我正在上课的示例

public class TestReduce
{
    private static Set<Integer> seed = ImmutableSet.of(1, 2);
    public static void main(String args[]) {
        List<Accumulator> accumulators = ImmutableList.of(new Accumulator(ImmutableSet.of(5, 6)), new Accumulator(ImmutableSet.of(7, 8)));

        accumulators.stream()
                .forEach(a -> {
                    seed = a.combineResult(seed);
                });

        System.out.println(seed);
    }
}

class Accumulator
{
    public Accumulator(Set<Integer> integers)
    {
        accumulatedNumbers = integers;
    }

    public Set<Integer> combineResult(Set<Integer> numbers) {
        // Do some manipulation for the numbers 
        return (the new numbers);
    }

    private Set<Integer> accumulatedNumbers;
}

我想将所有Accumulators简化为一组数字,但使用初始值。但是,我无法更改方法combineResult的签名。在示例中,我只是通过使用forEach来完成此操作的,但是我不确定是否有更干净的方法或java流方法来实现此目的?我尝试使用reduce,但无法完全理解reduce的参数。

java stream
1个回答
1
投票

这似乎不是一个好方法。您只是在合并一些集合。

如果无法更改combineResult的签名,则可以执行:

ImmutableSet<Integer> seed =
    Stream.concat(
        initialSet.stream(),
        accumulators.stream()
            // Essentially just extracting the set from each accumulator.
            // Adding a getter for the set to the Accumulator class would be clearer.
            .map(a -> a.combineResult(Collections.emptySet()))
            .flatMap(Set::stream))
        .collect(ImmutableSet.toImmutableSet());

对于一般化的combineResult,您不应使用reduce,因为该操作可能是非关联的。

在这种情况下,仅使用普通的旧循环就很容易。

Set<Integer> seed = ImmutableSet.of(1, 2);
for (Accumulator a : accumulators) {
  seed = a.combineResult(seed);
}
© www.soinside.com 2019 - 2024. All rights reserved.