简体   繁体   中英

What is the difference between these two random methods?

This is a rock, paper, scissors game. My question is, if i moved weapons.length in private Random r = new Random(weapons.length); it would give me an error. While if i moved weapons.length inside the method it would run successfully. What is the difference?

 public class Game {

private String[] weapons = {"rock", "paper", "scissor"};
private Random r = new Random(weapons.length);


public void thePick() {

    System.out.println(weapons[r.nextInt()]);

 }

}

vs

public class Game {

private String[] weapons = {"rock", "paper", "scissor"};
private Random r = new Random();


public void thePick() {

    System.out.println(weapons[r.nextInt(weapons.length)]);

 }
}

r.nextInt() would give you any random integer, regardless of the array being there. When you call private Random r = new Random(weapons.length); you are actually seeding the RNG with 3, and not setting an upper limit of 3.

It could give you 42, 2,000,000, -10, etc, etc. The array doesn't have an element in position 42, and you'd get an error as the seed of 3 will always yield a random value out of range. If it was not seeded (ie Random r=new Random() ) then there is a slim chance of getting a valid value, but that chance is extremely small.

For the second, you are picking a random int with a bound , namely from 0 to the length of the array(not including the upper bound).

So for your:

{"rock", "paper", "scissor"};

rock is element 0, paper is element 1, and scissors is element 2. The random.nextInt(weapons.length) call always returns an int from 0 to 2(as 3, the length, is NOT included).

The first one will throw ArrayIndexOutOfBoundsException every time. In fact it will always throw the exception

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1155099828
    at Game.thePick(Game.java:11)

Thank you @hexafraction for spotting that.

The second method won't print an exception, instead it will just pick a random choice.

The second delivers a value from 0 - 2
The first random delivers in whole int range, so it practically ever will throw an ArrayOutOfBoundsException.
But why you dont try out?

You should consider reading the respective Javadocs: Here is the constructor you are invoke in your first attempt: http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#Random%28long%29 You are actually providing a seed not getting a random number in a specified range. This means that calls to .nextInt() will return the same on every run of your application.

In your second attempt you are using the default contrusctor (initializes with the current time as seed) and calling a method that does the right thing: http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt%28int%29

Documentation is a wonderful thing. Use it wisely.

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