一个泛型方法,可以返回2个参数之间的随机整数,如ruby与rand(0..n)
。
有什么建议吗?
我的建议是extension上的IntRange函数来创建这样的randoms:(0..10).random()
从1.3开始,Kotlin自带多平台随机发生器。它在这个KEEP中描述。下面描述的扩展现在是part of the Kotlin standard library,只需使用它:
val rnds = (0..10).random()
在1.3之前,如果JDK> 1.6,我们在JVM上使用Random
甚至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
的用例,请参阅this alternative。
此外,请参阅此answer我的建议的变化。它还包括随机Char
s的扩展功能。
没有标准方法可以做到这一点,但您可以使用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<Int, Int>) = random(pair.first, pair.second)
fun main(args: Array<String>) {
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]
如果您要选择的数字不是连续的,则可以使用random()
。
用法:
val list = listOf(3, 1, 4, 5)
val number = list.random()
返回列表中的一个数字。
使用顶级函数,您可以实现与Ruby中完全相同的调用语法(如您所愿):
fun rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
用法:
rand(1, 3) // returns either 1, 2 or 3
首先,你需要一个RNG。在Kotlin中,您目前需要使用平台特定的(没有内置的Kotlin)。对于JVM来说,它是java.util.Random
。您需要创建它的实例,然后调用random.nextInt(n)
。
Kotlin标准库不提供随机数生成器API。如果您不在多平台项目中,最好使用平台api(问题的所有其他答案都谈论此解决方案)。
但是如果你处于多平台环境中,最好的解决方案是在纯kotlin中自己实现随机,以便在平台之间共享相同的随机数生成器。开发和测试更简单。
为了在我的个人项目中回答这个问题,我实现了一个纯粹的Kotlin Linear Congruential Generator。 LCG是java.util.Random
使用的算法。如果您想使用它,请点击此链接:https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
我的实施目的nextInt(range: IntRange)
为你;)。
关注我的目的,LCG适用于大多数用例(模拟,游戏等......),但由于此方法的可预测性,因此不适合加密使用。
在Kotlin 1.3中你可以这样做
val number = Random.nextInt(limit)
要在Kotlin中获取随机的Int编号,请使用以下方法:
import java.util.concurrent.ThreadLocalRandom
fun randomInt(rangeFirstNum:Int, rangeLastNum:Int) {
val randomInteger = ThreadLocalRandom.current().nextInt(rangeFirstNum,rangeLastNum)
println(randomInteger)
}
fun main() {
randomInt(1,10)
}
// Result – random Int numbers from 1 to 9
希望这可以帮助。
您可以创建扩展功能:
infix fun ClosedRange<Float>.step(step: Float): Iterable<Float> {
require(start.isFinite())
require(endInclusive.isFinite())
require(step.round() > 0.0) { "Step must be positive, was: $step." }
require(start != endInclusive) { "Start and endInclusive must not be the same"}
if (endInclusive > start) {
return generateSequence(start) { previous ->
if (previous == Float.POSITIVE_INFINITY) return@generateSequence null
val next = previous + step.round()
if (next > endInclusive) null else next.round()
}.asIterable()
}
return generateSequence(start) { previous ->
if (previous == Float.NEGATIVE_INFINITY) return@generateSequence null
val next = previous - step.round()
if (next < endInclusive) null else next.round()
}.asIterable()
}
Round Float值:
fun Float.round(decimals: Int = DIGITS): Float {
var multiplier = 1.0f
repeat(decimals) { multiplier *= 10 }
return round(this * multiplier) / multiplier
}
方法的用法:
(0.0f .. 1.0f).step(.1f).forEach { System.out.println("value: $it") }
输出:
值:0.0值:0.1值:0.2值:0.3值:0.4值:0.5值:0.6值:0.7值:0.8值:0.9值:1.0
超级骗子))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}
生成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
您可以创建一个类似于extension function的java.util.Random.nextInt(int)
,但是需要使用IntRange
而不是Int
作为其绑定:
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start)
}
您现在可以在任何Random
实例中使用它:
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
我的other answer随机字符的可能变化
为了获得随机Char
s,您可以定义这样的扩展函数
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()
instead of Random()
。
对于kotlinjs和其他不允许使用java.util.Random
的用例,this answer会有所帮助。
从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()
或利用Java Random
val random2 = Random().nextInt(10) + 1
从1.3开始,标准库为random提供了多平台支持,请参阅this的答案。
如果您正在使用Kotlin JavaScript并且无法访问java.util.Random
,则以下内容将起作用:
fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()
像这样使用:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
实现s1m0nw1的答案的另一种方法是通过变量访问它。并不是说它更有效,但它可以让你免于输入()。
val ClosedRange<Int>.random: Int
get() = Random().nextInt((endInclusive + 1) - start) + start
现在它可以这样访问
(1..10).random