BinaryOpertor for List <integer>添加列表

时间:2018-12-24 07:55:16

标签: java java-8 java-stream functional-interface

在上一个问题中,我先前曾问过Which FunctionalInterface should I use?

现在我正尝试添加到List<Integer>中,而不仅仅是两个整数ab ,这样每个索引都添加到另一个索引中清单。

我以前有

 BinaryOperator<Integer> binaryOperator = Integer::sum;

用于使用binaryOperator.apply(int a,int b)将两个整数相加。是否有类似

的方式
BinaryOperator<List<Integer>> binaryOperator = List<Integer>::sum;

然后在List<Integer> cList中得到结果?

3 个答案:

答案 0 :(得分:4)

如果您要对相应索引处的元素(在此特定情况下为求和)执行一些计算,则无需使用BinaryOperator,而使用IntStream.range来生成索引:

// generates numbers from 0 until list.size exclusive 
IntStream.range(0, list.size())....

// generates numbers from 0 until the minimum of the two lists exclusive if needed
IntStream.range(0, Math.min(list.size(), list2.size()))....

这种逻辑的通用名称是“ zip”;也就是说,当给定两个输入序列时,它会产生一个输出序列,其中使用某种功能将输入序列中位于相同位置的每两个元素组合在一起。

为此,标准库中没有内置方法,但是您可以找到一些通用实现here

例如,在链接的帖子的接受答案中使用zip方法,您可以简单地执行以下操作:

List<Integer> result = zip(f.stream(), s.stream(), (l, r) -> l + r).collect(toList());

或使用方法参考:

List<Integer> result = zip(f.stream(), s.stream(), Math::addExact).collect(toList());

其中fs是您的整数列表。

答案 1 :(得分:1)

您可以使用IntStream.range()遍历元素,然后使用mapToObj()将它们映射到它们的总和,并在第三个列表中将collect()映射到它们。

鉴于您的列表大小为 相同

List<Integer> first = List.of(); // initialised
List<Integer> second = List.of(); // initialised

您可以获得第三个列表:

List<Integer> third = IntStream.range(0, first.size())
                               .mapToObj(i -> first.get(i) + second.get(i))
                               .collect(Collectors.toList());

就BinaryOperator而言,您可以将其表示为:

BinaryOperator<List<Integer>> listBinaryOperator = (a, b) -> IntStream.range(0, first.size())
            .mapToObj(i -> first.get(i) + second.get(i))
//          OR from your existing code
//          .mapToObj(i -> binaryOperator.apply(first.get(i), second.get(i)))
            .collect(Collectors.toList());

或者您可以通过将逻辑抽象为一种方法并将其用作以下方式来使其更具可读性:

BinaryOperator<List<Integer>> listBinaryOperator = YourClass::sumOfList;

其中sumOfList定义为:

private List<Integer> sumOfList(List<Integer> first, List<Integer> second) {
    return IntStream.range(0, first.size())
            .mapToObj(i -> first.get(i) + second.get(i))
            .collect(Collectors.toList());
}

答案 2 :(得分:1)

您可以做的是定义自己的实用程序方法,其单一任务是 zipping 两个输入列表:

<T> List<T> zip(final List<? extends T> first, final List<? extends T> second, final BinaryOperator<T> operation)
{
    return IntStream.range(0, Math.min(first.size(), second.size()))
        .mapToObj(index -> operation.apply(first.get(index), second.get(index)))
        .collect(Collectors.toList());
}

这样,您可以将两个输入列表汇总为:

zip(first, second, Integer::sum)