我怎样才能在Kotlin中得到一个随机数字?

一个generics的方法,可以返回一个随机整数之间的2个参数,如ruby与rand(0..n)

任何建议?

生成from (包括) to (独占)之间的随机整数

 import java.util.Random val random = Random() fun rand(from: Int, to: Int) : Int { return random.nextInt(to - from) + from } 

我建议在ClosedRange上使用下面的扩展函数:

 fun ClosedRange.random() = Random().nextInt(endInclusive - start) + start 

像这样使用它:

 // will return an `Int` between 0 and 9 (incl.) (0..10).random() 

如果您正在使用JDK> = 1.7,请使用ThreadLocalRandom.current()而不是Random()

另请参阅此答案的变化。

你可以创建一个类似于java.util.Random.nextInt(int)的扩展函数 ,但是它的绑定需要一个IntRange而不是Int

 fun Random.nextInt(range: IntRange): Int { return range.start + nextInt(range.last - range.start) } 

你现在可以在任何实例中使用它:

 val random = Random() println(random.nextInt(5..9)) // prints 5, 6, 7, or 8 

如果你不想管理你自己的Random实例,那么你可以使用例如ThreadLocalRandom.current()定义一个方便的方法:

 fun rand(range: IntRange): Int { return ThreadLocalRandom.current().nextInt(range) } 

现在,您可以像在Ruby中一样获得一个随机整数,而无需首先声明一个Random实例:

 rand(5..9) // returns 5, 6, 7, or 8 

建立@ s1m0nw1优秀的答案我做了以下更改。

  1. (0..n)意味着包含在Kotlin中
  2. (0至n)意味着在Kotlin独家
  3. 为Random实例使用单例对象(可选)

码:

 private object RandomRangeSingleton : Random() fun ClosedRange.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start 

测试用例:

 fun testRandom() { Assert.assertTrue( (0..1000).all { (0..5).contains((0..5).random()) } ) Assert.assertTrue( (0..1000).all { (0..4).contains((0 until 5).random()) } ) Assert.assertFalse( (0..1000).all { (0..4).contains((0..5).random()) } ) } 

首先,你需要一个RNG。 在Kotlin中,您目前需要使用平台特定的平台(没有内置Kotlin)。 对于JVM,它是java.util.Random 。 你需要创建一个实例,然后调用random.nextInt(n)

没有这样的标准方法,但是使用Math.random()java.util.Random类可以轻松创建自己的方法。 这是一个使用Math.random()方法的例子:

 fun random(n: Int) = (Math.random() * n).toInt() fun random(from: Int, to: Int) = (Math.random() * (to - from) + from).toInt() fun random(pair: Pair) = random(pair.first, pair.second) fun main(args: Array) { val n = 10 val rand1 = random(n) val rand2 = random(5, n) val rand3 = random(5 to n) println(List(10) { random(n) }) println(List(10) { random(5 to n) }) } 

这是一个示例输出:

 [9, 8, 1, 7, 5, 6, 9, 8, 1, 9] [5, 8, 9, 7, 6, 6, 8, 6, 7, 9] 

使用顶级函数,您可以实现与Ruby中完全相同的调用语法(如您所愿):

 fun rand(s: Int, e: Int) = Random().nextInt(e + 1 - s) + s 

用法:

 rand(1, 3) // returns either 1, 2 or 3 

上面我的答案可能的变化

a)如果您希望0..10.random()也包含值10 ,则需要进行以下更改:

 fun ClosedRange.random() = Random().nextInt(endInclusive + 1 - start) + start 

b)为了得到随机的Char ,你可以定义如下函数:

 fun ClosedRange.random(): Char = (Random().nextInt(endInclusive.toInt() + 1 - start.toInt()) + start.toInt()).toChar() // will return a `Char` between A and Z (incl.) ('A'..'Z').random() 

如果您正在使用JDK> = 1.7,请使用ThreadLocalRandom.current()而不是Random()

如果您想选择的号码不是连续的,您可以在List上定义自己的扩展function:

 fun List<*>.randomElement() = if (this.isEmpty()) null else this[Random().nextInt(this.size)] 

用法:

 val list = listOf(3, 1, 4, 5) val number = list.randomElement() 

返回列表中的一个数字。

Kotlin标准库不提供随机数生成器API。 如果你不是在一个多平台的项目,最好使用平台API (所有其他答案的问题谈论这个解决方案)

但是,如果您处于多平台环境中,最好的解决方案是在纯kotlin中自行实现,以便在平台之间共享相同的随机数字生成器。 开发和测试更简单。

为了在我的个人项目中回答这个问题,我实现了一个纯Kotlin 线性同余发生器 。 LCG是java.util.Random使用的算法。 按照这个链接,如果你想使用它: https : //gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4

我的实现目的nextInt(range: IntRange)为你;)。

注意我的目的,LCG对大多数用例(模拟,游戏等)都有好处,但是由于这种方法的可预测性,不适合密码使用。