简体   繁体   中英

How to populate List<Integer> from IntStream?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM