Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BinaryOpertor for List<Integer> to add the lists

In previous question I asked previously Which FunctionalInterface should I use?

Now I was trying to add to List<Integer> and not just two Integers a and b, such that each index adds to the same index of another list.

I had previously

 BinaryOperator<Integer> binaryOperator = Integer::sum;

for adding two integers using binaryOperator.apply(int a,int b). Is there a similar way like

BinaryOperator<List<Integer>> binaryOperator = List<Integer>::sum;

and then get the result in List<Integer> cList?

like image 975
Mani Avatar asked May 17 '26 13:05

Mani


2 Answers

if you want to perform some computation on the elements at corresponding indices (in this specific case the summation) there's no need to use a BinaryOperator, instead use IntStream.range to generate the indices:

// 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()))....

The common name for this type of logic is "zip"; i.e. when given two input sequences it produces an output sequence in which every two elements from the input sequences at the same position are combined using some function.

There's no built-in method in the standard library for this, but you can find some generic implementations here.

for example, using the zip method in the accepted answer of the linked post, you could simply do:

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

or using method reference:

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

where f and s are your list of integers.

like image 112
Ousmane D. Avatar answered May 20 '26 04:05

Ousmane D.


You can use IntStream.range() to iterate over elements, then mapToObj() to map them to their sum and the collect() them in the third list.

Given that your lists are of same size

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

you can get the third list as :

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

In terms of BinaryOperator, you can represent it as :

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());

Or you can make it more readable by abstracting out the logic into a method and using it as :

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

where sumOfList is defined as :

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());
}
like image 31
Naman Avatar answered May 20 '26 02:05

Naman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!