简体   繁体   中英

Guava - how can I generate a random number using Range?

Google的Guava库提供了一个名为Range的优秀类,它有许多有用的方法,如greaterThan(x)open(x,y)等。我想知道是否有任何方法可以应用这种方法在Range生成一个随机数?

I would not suggest using a range for this basic application.

The easiest method to use is the already implemented Random class.

Here is how to use the class:

For getting a random integer of any value:

Random r = new Random();
r.nextInt();

For getting a random integer in a range of min x, max y:

Random r = new Random();
r.nextInt(y - x) + x;

This is the most basic way of getting a random number in a range. I bet there is a getMin and getMax method in the range class, so use that for x and y.

Also, if you want a random number greater than a min value of x, just do:

Random r = new Random();
Math.abs(r.nextInt().nextInt()) + x;

^The code above generates any positive integer, and the x ensures the min value.

-or-

nextInt(Integer.MAX_VALUE - (x + 1)) + (x + 1)

-as suggested by ColinD Hope this helps. -Classic

Like Louis says there's no built-in way to do this, but there are a couple of fairly straightforward options. Note that we have to assume all Range instances are bounded on both sides - you cannot select a random value from an unbounded or non-discrete range (eg (-∞..0] ).

The easiest to implement solution is to simply convert the Range into a ContiguousSet , from which you can select a random value in linear time . This has the advantage of working for any discrete type, not just Range<Integer> .

public static C random(Range<C> range, DiscreteDomain<C> domain) {
  Set<C> set = ContiguousSet.create(range, domain);
  int index = random.nextInt(set.size());
  return Iterables.get(set, index);
}

Of course constant time would be better, especially for large ranges. Canonicalizing the Range first reduces the number of cases we have to handle, and we can use the f(yx) + x pattern JClassic suggests.

public static int random(Range<Integer> range) {
  checkArgument(range.hasLowerBound() && range.hasUpperBound(),
      "Cannot select a random element from unbounded range %s", range);
  Range<Integer> canonical = range.canonical(DiscreteDomain.integers());
  return random.nextInt(canonical.upperEndpoint() - canonical.lowerEndpoint())
      + canonical.lowerEndpoint();
}

You can extend this easily for Long with Random.nextLong() (but note that Random.nextLong() cannot return all long values, so SecureRandom would be preferable).

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