简体   繁体   English

番石榴 - 如何使用Range生成随机数?

[英]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. 最简单的方法是使用已经实现的Random类。

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: 要获得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. 我敢打赌在范围类中有一个getMin和getMax方法,所以对x和y使用它。

Also, if you want a random number greater than a min value of x, just do: 此外,如果您想要一个大于x的最小值的随机数,只需执行以下操作:

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

^The code above generates any positive integer, and the x ensures the min value. ^上面的代码生成任何正整数,x确保最小值。

-or- -要么-

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

-as suggested by ColinD Hope this helps. - 由ColinD Hope建议这有帮助。 -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] ). 请注意,我们必须假设所有Range实例都在两侧有界 - 您无法(-∞..0]界或非离散范围中选择随机值(例如(-∞..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 . 最简单的解决方案是简单地将Range转换为ContiguousSet ,您可以从中选择线性时间的随机值 This has the advantage of working for any discrete type, not just Range<Integer> . 这样做的优点是适用于任何离散类型,而不仅仅是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. 规范化 Range首先减少了我们必须处理的案例数量,我们可以使用JClassic建议的f(yx) + x模式。

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). 您可以使用Random.nextLong()轻松地为Long扩展它(但请注意, Random.nextLong()不能返回所有long值,因此最好使用SecureRandom )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM