I want to populate List with numberOfElements
elements of random Integers in a range of 0 to numberOfElements/10
. Why method populateListStream1()
works and populateListStream2()
does not work?
public static List<Integer> populateListStream1(int numberOfElements) {
return Stream.generate(new Random()::nextDouble)
.limit(numberOfElements)
.map(e -> (int)(e*numberOfElements/10))
.collect(Collectors.toList());
}
public static List<Integer> populateListStream2(int numberOfElements) {
return IntStream.range(0,numberOfElements)
.map(e -> random.nextInt(numberOfElements/10))
.collect(Collectors.toList());
}
In the second example nextInt()
from the Random
class returns a primitive int
, which can't be collected to a List
. Add a call to boxed
, which will convert the int
's to their wrapper class Integer
:
public static List<Integer> populateListStream2(int numberOfElements){
return IntStream.range(0,numberOfElements)
.map(e -> random.nextInt(numberOfElements/10))
.boxed()
.collect(Collectors.toList());
}
But the first one also returned a primitive int through casting!
Yes, but it was in a Stream
, so it was autoboxed to an Integer
. You can tell by running:
Stream.generate(new Random()::nextDouble)
.limit(numberOfElements)
.map(e -> (int)(e*numberOfElements/10))
.peek(e -> System.out.println(e.getClass()))
.collect(Collectors.toList());
Which prints:
class java.lang.Integer
The latter was an IntStream
. One of IntStream
's benefits is to avoid auto boxing and unboxing. It won't box unless you explicitly call boxed()
Also note that there are methods from the Random
class that already return a Stream
of random numbers such as ints()
and doubles()
Box int
it to it's wrapper corresponding class Integer
. Also, you can try something like:
public static List<Integer> populateListStream3(int numberOfElements) {
List<Integer> listOfIntegers = new Random().ints(numberOfElements, 0, numberOfElements/10).boxed().collect(Collectors.toList());
return listOfIntegers;
}
The second one does not work, because you are using an IntStream
which contains primitive int types. You have to call boxed()
before map()
. But a better solution would be to use mapToObj()
instead of map()
:
public static List<Integer> populateListStream2(int numberOfElements) {
return IntStream.range(0, numberOfElements)
.mapToObj(e -> random.nextInt(numberOfElements / 10))
.collect(Collectors.toList());
}
In this case the values are autoboxed as they are in your populateListStream2()
method.
Alternatively I would recommend using Random.ints()
to generate a Stream of ints.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.