Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IntStream rangeClosed unable to return value other than int [duplicate]

Why is this getting error? I thought map can return any value.

var s = IntStream.rangeClosed(1, 5).map(String::valueOf).collect(Collectors.toList());

| Error: | incompatible types: bad return type in method reference | java.lang.String cannot be converted to int | var s = IntStream.rangeClosed(1, 5).map(String::valueOf).collect(Collectors.toList()); |
^-------------^

like image 936
Julez Avatar asked Dec 31 '18 06:12

Julez


People also ask

What is IntStream of in Java?

Return Value : IntStream of(int… values) returns a sequential ordered stream whose elements are the specified values. Example 1 : Java.

What is IntStream rangeClosed?

IntStream rangeClosed() method in Java The rangeClosed() class in the IntStream class returns a sequential ordered IntStream from startInclusive to endInclusive by an incremental step of 1. This includes both the startInclusive and endInclusive values.

What is instream in java8?

Introduced in Java 8, the Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.

What is the return value of IntStream?

Return Value : IntStream of (int… values) returns a sequential ordered stream whose elements are the specified values. // elements are the specified values. // elements are the specified values.

What is IntStream rangeclosed () in Java?

IntStream rangeClosed () in Java Last Updated : 06 Dec, 2018 IntStream rangeClosed (int startInclusive, int endInclusive) returns an IntStream from startInclusive (inclusive) to endInclusive (inclusive) by an incremental step of 1.

What is IntStream class in Java?

Java IntStream class is an specialization of Stream interface for int primitive. It represents an stream of primitive int-valued elements supporting sequential and parallel aggregate operations.

What is the difference between IntStream and longstream methods?

Both the methods take a start value and an end value which are of type int for IntStream and long for LongStream. The output of the methods is a primitive stream with the type ( int / long) of elements based on class on which the static methods are called.


Video Answer


4 Answers

Use mapToObj:

var s = IntStream.rangeClosed(1, 5).mapToObj(String::valueOf).collect(Collectors.toList());

map of IntStream can only map an int value to another int value. It accepts an IntUnaryOperator (which accepts an int and returns an int) as the mapper function, and returns an IntStream.

On the other hand, mapToObj allows you to map an int value to any reference type, and thus transform the IntStream to a Stream<SomeReferenceType>. It accepts an IntFunction<? extends U> (which accepts an int and returns a reference type) as the mapper function, and returns a Stream<U>.

like image 164
Eran Avatar answered Oct 22 '22 12:10

Eran


Use mapToObj instead :

IntStream.rangeClosed(1, 5).mapToObj(String::valueOf).collect(Collectors.toList());
like image 28
Nicholas Kurian Avatar answered Oct 22 '22 14:10

Nicholas Kurian


While the aforementioned answers are correct and mapToObj is the idiomatic approach to proceed with, I think it's important to understand why the problem arises and thus in future cases, you'll know how to decipher the problem simply by going through the documentation.

it's a very important skill for a programmer to dig into the documentation when not understanding the workings of a specific method.

So, let's go through the relevant stream pipeline operations:

IntStream.rangeClosed returns an IntStream as per the documentation:

Returns a sequential ordered IntStream from startInclusive (inclusive) to endInclusive (inclusive) by an incremental step of 1.

invoking map on an IntStream is expected to return an IntStream as per the documentation:

Returns a stream consisting of the results of applying the given function to the elements of this stream.

As well as that it's important to note that the method declaration for map is as follows:

IntStream map(IntUnaryOperator mapper)

i.e. it takes a IntUnaryOperator which in fact represents an operation on a single int-valued operand that produces an int-valued result.

However, you're passing a function String::valueOf which consumes an int as we're dealing with an IntStream and returns a String thus not compliant with IntUnaryOperator and this is the cause of the problem.

Whenever you want to take a primitive stream specialization and perform some mapping function and in turn yield a Stream<R> as a result then mapToObj is the way to go.

mapToObj is declared as:

mapToObj(IntFunction<? extends U> mapper)

IntFunction represents a function that accepts an int-valued argument and produces a result and this result is of type R which means you'll have a Stream<R> after the mapToObj.

like image 42
Ousmane D. Avatar answered Oct 22 '22 13:10

Ousmane D.


Alternatively, you could use IntStream.boxed as :

var s = IntStream.rangeClosed(1, 5) // IntStream
                 .boxed() // Stream<Integer>
                 .map(String::valueOf) // Stream<String>
                 .collect(Collectors.toList());

since the IntStream originally is a sequence of primitive int-values elements.


Another variant of performing such an operation would be :

var s = IntStream.rangeClosed(1, 5)
                 .boxed()
                 .map(a -> Integer.toString(a))
                 .collect(Collectors.toList());
like image 36
Naman Avatar answered Oct 22 '22 14:10

Naman