30

I need to generate some random booleans. However I need to be able to specify the probability of returning true. As a results doing:

private Random random = new Random();
random.nextBoolean();

will not work.

One possible solution would be:

private Random random = new Random()

public boolean getRandomBoolean(float p){
    return random.nextFloat() < p;
}

I was wondering if there is a better or more natural way of doing this.

EDIT: I guess I am asking whether there is a library class that provides a nextBoolean(float probability) method.

5
  • 6
    What sort of "better" are you looking for? That looks reasonable to me...
    – Jon Skeet
    Jun 28, 2013 at 7:54
  • 1
    These are two (essentially) separate problems, so should be asked in two separate posts... Jun 28, 2013 at 7:55
  • @JonSkeet I guess I was hoping for something along the lines of Random.nextBoolean(long probability)
    – diestl
    Jun 28, 2013 at 7:56
  • I've snipped out your second question, please post it separately if you want an answer for it. I've also voted to close this question, as it is primarily opinion-based. Jun 28, 2013 at 8:00
  • Thanks. I'll edit the question so it is less opinion based.
    – diestl
    Jun 28, 2013 at 8:03

8 Answers 8

10

I was wondering if there is a better or more natural way of doing this.

The approach you're using already is fine.

* As far as I know, there's not a standard Java method that will make this code any shorter.


* For non-cryptographic purposes.

1
4

1) Yes, i think your approach is valid and I don't see another easier way.

2) There is a library for handling random numbers of different statistical distributions:

http://introcs.cs.princeton.edu/java/22library/StdRandom.java.html

0
3

Here's what I'm using. Very similar to FracturedRetina's answer.

Random random = new Random();

// 20% chance
boolean true20 = (random.nextInt(5) == 0) ? true : false;

// 25% chance
boolean true25 = (random.nextInt(4) == 0) ? true : false;

// 40% chance
boolean true40 = (random.nextInt(5) < 2) ? true : false;
2
  • 4
    The ternary operator is totally redundant. Why not just boolean true20 = (random.nextInt(5) == 0) ?
    – Oneiros
    Oct 11, 2017 at 14:25
  • You know how when you learn a new thing, it's useful in every situation? I completely agree that it's redundant.
    – bobanahalf
    Oct 12, 2017 at 15:33
1

The MockNeat library implements this feature.

Example for generating a boolean value that has 99.99% of being true:

MockNeat m = MockNeat.threadLocal();
boolean almostAlwaysTrue = m.bools().probability(99.99).val();
0
    public boolean getBiasedRandom(int bias) {
      int c;
      Random t = new Random();
     // random integers in [0, 100]
      c=t.nextInt(100);
      if (c>bias){return false;
      }
      else{return true;}
      }

This one is based on percentage...

-1

Expanding on user2495765's answer, you can make a function which takes an input ratio (as two values chance:range see code)

public class MyRandomFuncs {
    public Random rand = new Random();

    boolean getBooleanAsRatio(int chance, int range) {
        int c = rand.nextInt(range + 1);
        return c > chance;
    }

}

Depending on what you intend to do, you probably don't want to initalize Random from within your method but rather use as a class variable (as in the code above) and call nextInt() from within your function.

-2

Your way is probably better, code golf-wise, but another way to do it is like this:

public boolean getRandomBoolean() {
    Random random = new Random();
    //For 1 in 5
    int chanceOfTrue = 5;

    if (random.nextInt(chanceOfTrue) == 0) {
        return true;
    } else {
        return false;
    }
}

Or for 2 in 5, try this:

public boolean getRandomBoolean() {
    Random random = new Random();
    //For 2 in 5
    int chanceOfTrue = 5;
    int randInt = random.nextInt(chanceOfTrue);

    if (randInt == 0 || randInt == 1) {
        return true;
    } else {
        return false;
    }
}
-2

Random object needs to be intialized already.

public static boolean flipRandom(double probability) {
    Validate.isBetween(probability, 0, 1, true);
    if(probability == 0)
        return false;
    if(probability == 1)
        return true;
    if(probability == 0.5)
        return random.nextBoolean();
    return random.nextDouble() < probability ? true : false;
}
1
  • The validation is reasonable, the rest makes the code unnecessarily less readable. Keep it simple
    – Oneiros
    Oct 11, 2017 at 14:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.