3

I'm just learning the java.util.stream API and I'm looking for a way to quickly fill up a Collection with some data.

I've come up with this code to add 5 random numbers:

List<Integer> lottery = Stream.of(random.nextInt(90), random.nextInt(90), random.nextInt(90),random.nextInt(90),
random.nextInt(90)).collect(Collectors.toList());

That would be however a problem in case I have to add hundreds of items. Is there a more concise way to do it using the java.util.stream API?

(I could obviously loop in the ordinary way...)

Thanks

Nayantara Jeyaraj
  • 2,624
  • 7
  • 34
  • 63
Carla
  • 3,064
  • 8
  • 36
  • 65
  • 5
    check out `IntStream.range`. here https://stackoverflow.com/a/25793191/3959856 – Jack Flamp Mar 27 '18 at 07:36
  • 2
    Possible duplicate of [Java 8 - what is the correct way to fill an arraylist with the same object using Stream API?](https://stackoverflow.com/questions/40258194/java-8-what-is-the-correct-way-to-fill-an-arraylist-with-the-same-object-using) – ashwinsakthi Mar 27 '18 at 07:38
  • IntStream.range(0,5).map(i -> random.nextInt(90)).boxed().collect(Collectors.toList()); – Volodymyr Demenkov Mar 27 '18 at 07:39
  • 3
    Answer from duplicate noted by @ashwinsakthi : `Stream.generate(() -> random.nextInt(90)).limit(5).collect(toList());` – Patrick Parker Mar 27 '18 at 07:43
  • Seems to be a duplicate, but see Olivier's answer - this has a special wrinkle. – David Mar 27 '18 at 09:39

3 Answers3

4

In this case the stream API only makes things more complicated vs. a regular loop, but you could create an IntStream (or Stream<Integer> depending on where you convert the int to Integer) that generates infinite random numbers with

IntStream rndStream = IntStream.generate(() -> rnd.nextInt(90));

Now you can use limit() to create non-infinite substreams that can be collected, such as

rndStream.limit(5).boxed().collect(Collectors.toList());

However this is just stream trickery and has no advantages over say having a method called List<Integer> getRandoms(int number) with a regular loop inside.


There's no reason to use the code displayed in this answer as it's less readable and more complex than alternatives. This just demonstrates how to get finite amounts of elements from an infinitely generated stream.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • @Carla there's nothing cool about writing unreadable overly complex code. Use streams and regular loops where they make sense. Streams are **not** a replacement for "old" loops. – Kayaman Mar 27 '18 at 08:26
4

Use Random.ints(long, int, int)

Everyone else on this page is generating the stream because they can, but Java already has such an out of the box method, Random.ints(long, int, int), available since Java 8 (and therefore the beginning of streams).

Just use it like this:

List<Integer> lottery = rnd.ints(5, 0, 90)
                           .boxed()
                           .collect(Collectors.toList());

The instruction rnd.ints(5L, 0, 90) means: "create a stream of 5 integers between 0 (included) and 90 (excluded)". So if you want 100 numbers instead of 5, just change 5 to 100.

Olivier Grégoire
  • 33,839
  • 23
  • 96
  • 137
  • Wow, great method - I did not know about that. Makes you think about discoverability of stuff in the JDK. – David Mar 27 '18 at 09:38
0

This should do:

List<Integer> randomList = new ArrayList<>();
SecureRandom random = new SecureRandom();
IntStream.rangeClosed(1,100).forEach(value->randomList.add(random.nextInt(90)));
AstroMan
  • 61
  • 1
  • 10