'How to compare the elements of an ArrayList with every element of another ArrayList using Stream API of Java 8?
I have two Sorted ArrayList of same size, namely team_A & team_B, in which comparing every element of team_A with team_B to find the powerDiff > 0. After finding the powerDiff greater than 0, then removing that element from the team_B to reduce the number of iteration in the next cycle.
long calculateWin(){
    int wins = 0;
    int tempIndex=0;
    boolean flag = false;
    long powerDiff=0;
    for(int i=0; i<team_A.size(); i++) {
        for(int j=0; j<team_B.size(); j++) {
            powerDiff = team_A.get(i) - team_B.get(j);
            if(powerDiff>0) {
                wins++;
                tempIndex=j;
                flag=true;
                break;
            }
        }
        if(flag) {
            team_B.remove(tempIndex);
            flag = false;
        }
    }
    return wins;
}
The above code is working fine but due to complexity I want to optimize this code using the Stream API of Java 8.
Solution 1:[1]
Could you please try this one;
public static long calculateWinJava8(){
    List<Long> team_A = new ArrayList(Arrays.asList(50L,60L,70L,80L,90L,100L));
    List<Long> team_B = new ArrayList(Arrays.asList(30L,40L,25L,80L,55L,200L,250L));
    int wins = team_B.size();
    team_A.stream().forEach(itemA->{
         List<Long> removeItems = team_B.stream().filter(itemB-> (itemA-itemB)>0).collect(Collectors.toList());
         team_B.removeAll(removeItems);
    });
    System.out.println("result team_B : "+team_B.toString());
    wins = wins - team_B.size();
    System.out.println("wins : "+wins);
    return 0;
}
    					Solution 2:[2]
There isn't a good way with the standard JDK because it's lacking basic constructs like a .zip() operator and a Tuple class. If it did it would look something like this:
val wins = team_a.zip(team_b)
                .filter { tuple -> tuple.first > tuple.second }
                .count()
That's kotlin but there are a ton of java libaries that offer a .zip() and Tuple.
If you really want to do it with just the JDK it'd be something like:
long wins = IntStream
        .range(0, Math.min(team_a.size(), team_b.size()))
        .filter(i -> team_a.get(i) > team_b.get(i))
        .count();
This works but isn't ideal since you are reaching outside the pipeline unlike the first example.
Solution 3:[3]
Ok, let's untangle the logic a bit.
You check for for each pair if a[i] > b[j]. And if it matches, you remove b[j].
Good. long has a total order, so, we only need it's maximum.
long max_a = team_a.stream().mapToLong(a -> a).max().getAsLong();
Now that we have the most powerful of team a, we check how many they can defeat:
long wins = team_b.stream().filter(b -> a > b).count();
And that's it.
Wait. I did not notice the key word "sorted" in your question.
This means we can do a binary search.
First we get the maximum. I assume the list are in ascending order.
long max_a = team_a.get(team_a.size()-1);
Now we need to find where we have to make the cut:
int idx = Collections.binarySearch(team_b, max_a);
Note that Collections.binarySearch can return a negative number if the maximum is not in the list. But we are only interested in the number of smaller items in the list.
if (idx < 0)
    idx = -idx - 1
Now idx contains the number of elements smaller than the largest element in the first list. Return that:
return idx;
    					Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | KEYSAN | 
| Solution 2 | |
| Solution 3 | 
