10

I have two integer arrays e.g. -

int[] a = {2, 7, 9}

int[] b = {4, 2, 8}

I want to compare it element by element i.e. 2 to 4 then 7 to 2 and finally 9 to 8. Each comparison result will be stored in a list.

This is pretty easy to do in the traditional Java ways. But I want to use Stream here. Any pointers?

4 Answers 4

8

You may do it like so,

List<Boolean> equalityResult = IntStream.range(0, a.length).mapToObj(i -> a[i] == b[i])
                .collect(Collectors.toList());

Precondition: both the arrays are of same size.

Sign up to request clarification or add additional context in comments.

Comments

3

Assuming the length of both the input arrays are same

List<Integer> list = IntStream.range(0, a.length).mapToObj(i -> Integer.compare(a[i], b[i]))
            .collect(Collectors.toCollection(() -> new ArrayList<>(a.length)));

3 Comments

You can use toList() instead of toCollection(...)
@PeterLawrey Thanks for the suggestion, I did think of that as well. Was awaiting someone to review this and help me understand if initializing array with capacity as in () -> new ArrayList<>(a.length) can be of any good than Supplier<List<T>>) ArrayList::new (default capacity maybe!) with this Collectors implementation?
There is no good solution regarding the capacity yet. Initializing an ArrayList with the number of expected elements might be good for a sequential stream, but cause oversized temporary arrays with a parallel stream. Today, the best solution would be List<Integer> list = Arrays.asList( /* your stream operation */ .toArray(Integer[]::new));, as this will utilize the known number of elements, even in the parallel case, letting all threads write into the one final array, when the sizes are predictable, like in this specific case. But don’t try to optimize when there is no performance problem.
2

Same as other answers with a bit difference

List<Integer> result = IntStream.rangeClosed(0,a.length-1)
            .boxed()
            .map(i->Integer.compare(a[i],b[i]))
            .collect(Collectors.toList());

2 Comments

You can use .mapToObj instead of .boxed().map
And you can use range(0, a.length) instead of rangeClosed(0, a.length-1)
2

You're essentially looking for the functionality of a Zip operation (which is not available in Java yet).

To get a set of booleans, as a result, I would recommend:

boolean[] accumulator = new boolean[a.length];
IntStream.range(0, a.length)
         .forEachOrdered(i -> accumulator[i] = a[i] == b[i]);

and respectively to get the result as an int between corresponding elements in both arrays:

int[] ints = IntStream.range(0, a.length)
                      .map(i -> Integer.compare(a[i], b[i]))
                      .toArray();

2 Comments

I am not sure forEachOrdered would make a difference in this case. c.f. forEach
@PeterLawrey it’s a matter of preference in this specific case I guess. So yes you’re correct one could have simply used forEach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.