Search code examples
javajava-stream

Determine a winner based on a single random value and an array of probabilities using java streams


I have an array of probability values that add up to 1.0. I want to determine one winner element based on a random number between 0 and 1:

double probabilities[] = {.2, .75, .05};

double randomValue = new Random().nextDouble();
int winner = -1;
Iterator<Double> iterator = Arrays.stream(probabilities).iterator();
double probability = 0;
do {
    winner++;
    probability += iterator.next();
} while (probability < randomValue);

I do want to break when the winner is known. How would I do this using streams?


Solution

  • Streams are not always the best answer but if your probability array contains increasing sums you can do it like this.

    double probabilities[] = {.2, .95, 1.0}; // increasing
    double winningProb = Arrays.stream(probabilities)
        .filter(p -> p >= randomValue).findFirst().getAsDouble();
     
    System.out.println(winningProb); // answer matches your other method. 
    

    You can also convert probability array to increasing sums as follows:

    System.out.println("Before: " + Arrays.toString(probabilities));
    Arrays.parallelPrefix(probabilities, (a,b)->a + b);       
    System.out.println("After:  " + Arrays.toString(probabilities));
    

    prints

    Before: [0.2, 0.75, 0.05]
    After:  [0.2, 0.95, 1.0]