Finding an odd number from int[] array using Stream

Viewed 5018

I created an array and trying to use streams for finding the first odd number as follows:

int[] arr = new int[]{2, 4, 6, 8, 9, 12};
int oddOne = Stream.of(arr).filter(i -> i % 2 != 0).findFirst().get();
                                   // fails above

Error: | incompatible types: int[] cannot be converted to int

What am I doing wrong? How do I fix this?

4 Answers

You need to use Arrays.stream():

Arrays.stream(arr).filter(i -> i % 2 != 0).findFirst().getAsInt();

Which:

Returns a sequential IntStream with the specified array as its source.

As of now you are using the overloaded method Stream.of(T t) which simply:

Returns a sequential Stream containing a single element.

So it will only be a Stream of the single int[]


Also as nullpointer noted, calling get() without ensuring there is in fact an odd number in the Array will cause an error. It is best to use orElse() to return a default value if no odd number is present

You're trying to access int[] and not integer inside your filter. One way to resolve that would be to use IntStream with the help of flatMapToInt as:

int oddOrMin = Stream.of(arr) // Stream<int[]> and not integers
                     .flatMapToInt(Arrays::stream) // IntStream
                     .filter(i -> i % 2 != 0)
                     .findFirst() // OptionalInt
                     .orElse(Integer.MIN_VALUE); //default to some value

Simply you can also use IntStream to stream int[]

int[] arr = new int[]{2, 4, 6, 8, 9, 12};
int result = IntStream.of(arr).filter(i->i%2 !=0).findFirst().getAsInt();
System.out.println(result); //9

If you don't have any odd numbers then public int getAsInt() throws NoSuchElementException.

If a value is present in this OptionalInt, returns the value, otherwise throws NoSuchElementException.

So as @nullpointer suggestion always recommended to use orElse(int other)

public int orElse(int other)

Varargs are tricky. The signature of Stream.of() is Stream.of(T ...arg). Where T can be any class. But you are passing an array of native int which does not work. Instead it thinks the whole array is one object. Problem arises when you use an array of native types. Your code gives a stream of just one element of type int[]. You could rather use :

Integer[] arr = new Integer[]{2, 4, 6, 8, 9, 12};

You can simply use this or use Arrays.stream(arr) as others have suggested.

Related