1

how can create reproducable random numbers in java 8+ parallel Streams?

Example:

Random r = new Random(1337);

Arrays.stream(new int[]{1,2,3})
.parallel()
.map(i -> i + r.nextInt(10))
.forEach(i -> System.out.println(i));

Random and ThreadLocalRandom are not generating the same sequence if i execute serveral times.

My expected output is that if i execute this Code snippet serveral times i get always the same output. I dont need a random sequence of ints. I need that the same random number is generate for the same i.

TTho Einthausend
  • 609
  • 4
  • 13
  • what is ur expected output ? do you want random sequence ? – Ryuzaki L Dec 03 '20 at 21:22
  • Added clarification – TTho Einthausend Dec 03 '20 at 21:29
  • 1
    “the same random number … for the same `i`”… then how about using `i` as seed, `.map(i -> i + new Random(i).nextInt(10))`? But mind that a parallel stream with an unordered `forEach` won’t provide the same output for different runs. And, by the way, instead of `Arrays.stream(new int[]{1,2,3})`, you can simply write `IntStream.of(1, 2, 3)` or `IntStream.rangeClosed(1, 3)`. – Holger Dec 04 '20 at 08:34

1 Answers1

2

Update:

Based on the valuable comment by Holger, given below should be the right way of doing it:

Arrays.stream(new int[]{1,2,3})
.parallel()
.map(i -> i + new Random(i).nextInt(10))
.forEach(i -> System.out.println(i));

Using i as seed, i.e. .map(i -> i + new Random(i).nextInt(10)) will still reproducibly get the same random number for a particular i, but not a predictable constant value as returned by new Random(1337).nextInt(10).

Original answer:

Do it as follows:

Arrays.stream(new int[]{1,2,3})
.parallel()
.map(i -> i + new Random(1337).nextInt(10))
.forEach(i -> System.out.println(i));

Demo:

import java.util.Arrays;
import java.util.Random;

public class Main {
    public static void main(String args[]) {
        for (int k = 1; k <= 100; k++) {
            Arrays.stream(new int[]{1,2,3})
            .parallel()
            .map(i -> i + new Random(1337).nextInt(10))
            .forEach(i -> System.out.println(i));
        }
    }
}
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • @Holger - Sorry, I didn't read your comment properly :(. I agree that the statement, `Random r = new Random(1337);` was pointless; I had forgotten to remove it from the code. I've done it now. – Arvind Kumar Avinash Dec 04 '20 at 08:41
  • 1
    There’s still the issue that `new Random(1337).nextInt(10)` is always one, which reminds me on [this one](https://dilbert.com/strip/2001-10-25). To make the use of `Random` less pointless, I’d use `i` as seed, i.e. `.map(i -> i + new Random(i).nextInt(10))`. That way, you still reproducibly get the same random number for a particular `i`, but not a predictable constant value. – Holger Dec 04 '20 at 08:46
  • @Holger - Sorry, I was writing [another answer](https://stackoverflow.com/a/65140910/10819573) and I just went through your comment. The link to the comics is great . I will update the answer right now to incorporate your valuable recommendation...and thanks for always guiding me! – Arvind Kumar Avinash Dec 04 '20 at 09:31