有一种通用的方法可以返回两个参数之间的随机整数,就像 Ruby 中使用 rand(0..n)
一样。
有什么建议吗?
我建议在IntRange上创建一个扩展函数,以此方式生成随机数:(0..10).random()
从1.3版本开始,Kotlin自带一个多平台的Random生成器。它在这个KEEP中有描述。下面描述的扩展现在已经成为Kotlin标准库的一部分,可以像这样使用:
val rnds = (0..10).random() // generated random from 0 to 10 included
1.3版本之前,在JVM上我们使用Random
甚至在JDK>1.6时使用ThreadLocalRandom
。
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
使用方式如下:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
如果您希望该函数仅返回1,2,...,9
(不包括10
),请使用使用until
构造的范围:
(0 until 10).random()
如果你正在使用JDK > 1.6,那么请使用ThreadLocalRandom.current()
而不是Random()
。
KotlinJs和其他变体
对于kotlinjs和其他不允许使用java.util.Random
的用例,请参见这个替代方案。
此外,还可以查看此答案以获取我的建议的其他变体。它还包括一个用于随机生成Char
的扩展函数。
生成一个介于from
(包含)和to
(不包含)之间的随机整数
import java.util.Random
val random = Random()
fun rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
从 Kotlin 1.2 开始,你可以这样写:
(1..3).shuffled().last()
需要注意的是它的时间复杂度为 O(n),但对于小型列表(尤其是唯一值的列表)来说还是可以接受的 :D
在 Kotlin SDK >=1.3 中,您可以这样做:
import kotlin.random.Random
val number = Random.nextInt(limit)
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start + 1)
}
Random
实例:val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, 8, or 9
Random
实例,那么你可以定义一个方便的方法,例如使用ThreadLocalRandom.current()
:fun rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
rand(5..9) // returns 5, 6, 7, 8, or 9
关于生成随机字符的另一篇回答的可能变化
为了获取随机的Char
,你可以定义一个扩展函数,如下所示:
fun ClosedRange<Char>.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.6,请使用 ThreadLocalRandom.current()
代替 Random()
。
对于 kotlinjs 和其他不允许使用 java.util.Random
的用例,这个答案 会有所帮助。
从 1.3 版本开始,Kotlin 自带了自己的多平台随机数生成器。其在这篇 KEEP 中有描述。现在,您可以直接使用 Kotlin 标准库中的扩展而无需定义它:
('a'..'b').random()
在@s1m0nw1的出色回答基础上,我做了以下更改。
代码:
private object RandomRangeSingleton : Random()
fun ClosedRange<Int>.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())
}
)
}
在范围[1, 10]内随机生成数字的示例
val random1 = (0..10).shuffled().last()
val random2 = Random().nextInt(10) + 1
shuffled()
将返回一个列表。想象一下,如果您传递(0..Integer.MAX_VALUE)
会发生什么。 - deviant实现s1m0nw1答案的另一种方法是通过变量访问它。虽然这并没有更高效,但它可以节省您不必键入()的麻烦。
val ClosedRange<Int>.random: Int
get() = Random().nextInt((endInclusive + 1) - start) + start
现在可以像这样访问它
(1..10).random
java.util.Random
? - Simon Forsbergval rnds = (0..10).random()
实际生成从 0 到 10(包括 10 和 0)的随机数。 - xstIntRange
,其中有两个整型字段表示范围的起点和终点。然后IntRange.random
方法会调用nextInt(IntRange)
方法,它只是从start
到endInclusive
包装了一下nextInt
. - Salem