可以在2个参数之间返回随机整数的泛型方法,如ruby与rand(0..n)
一样。
有什么建议吗?
答案 0 :(得分:264)
我的建议是在extension上设置IntRange函数来创建这样的randoms:(0..10).random()
从1.3开始,Kotlin自带多平台随机发生器。它在KEEP中有所描述。下面描述的扩展现在是part of the Kotlin standard library,只需使用它:
val rnds = (0..10).random()
在1.3之前,如果我们在JDK>上,我们在JVM上使用Random
甚至ThreadLocalRandom
。 1.6。
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和其他变体
对于不允许使用java.util.Random
的kotlinjs和其他用例,请参阅this alternative。
另外,请参阅此answer了解我的建议的变体。它还包括随机Char
的扩展函数。
答案 1 :(得分:40)
生成from
(含)和to
之间的随机整数(不包括)
import java.util.Random
val random = Random()
fun rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
答案 2 :(得分:27)
从kotlin 1.2开始,你可以写:
(1..3).shuffled().last()
请注意它是大O(n),但是对于一个小的列表(特别是唯一值),它没关系:D
答案 3 :(得分:10)
您可以创建一个类似于extension function的java.util.Random.nextInt(int)
,但其IntRange
代替Int
的<{3}}
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
答案 4 :(得分:8)
Possible Variation to my other answer for random chars
In order to get random Char
s, you can define an extension function like this
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()
If you're working with JDK > 1.6, use ThreadLocalRandom.current()
instead of Random()
.
For kotlinjs and other use cases which don't allow the usage of java.util.Random
, this answer will help.
As of 1.3, Kotlin comes with its own multiplatform Random generator. It is described in this KEEP. You can now directly use the extension as part of the Kotlin standard library without defining it:
('a'..'b').random()
答案 5 :(得分:7)
基于@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())
}
)
}
答案 6 :(得分:5)
示例范围为[1,10]
val random1 = (0..10).shuffled().last()
或利用Java Random
val random2 = Random().nextInt(10) + 1
答案 7 :(得分:4)
从1.3开始,标准库为random提供了多平台支持,请参阅this answer。
如果您使用的是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()
答案 8 :(得分:4)
实现s1m0nw1答案的另一种方法是通过变量访问它。并不是说它更有效,但是它使您不必键入()。
val ClosedRange<Int>.random: Int
get() = Random().nextInt((endInclusive + 1) - start) + start
现在可以这样访问
(1..10).random
答案 9 :(得分:2)
使用顶级函数,您可以实现与Ruby中完全相同的调用语法(如您所愿):
fun rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
用法:
rand(1, 3) // returns either 1, 2 or 3
答案 10 :(得分:2)
如果您要选择的号码不是连续的,您可以使用random()
。
用法:
val list = listOf(3, 1, 4, 5)
val number = list.random()
返回列表中的一个数字。
答案 11 :(得分:2)
没有标准方法可以执行此操作,但您可以使用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]
答案 12 :(得分:1)
Kotlin标准库不提供随机数生成器API。如果您不在多平台项目中,最好使用平台api (问题的所有其他答案谈论此解决方案)。
但是如果你处于多平台环境中,最好的解决方案就是在纯kotlin中自己实现随机,以便在平台之间共享相同的随机数生成器。对开发和测试来说更简单。< / p>
为了在我的个人项目中回答这个问题,我实现了一个纯粹的Kotlin Linear Congruential Generator。 LCG是java.util.Random
使用的算法。如果您想使用它,请点击此链接:
https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
我的实施目的nextInt(range: IntRange)
;)。
关注我的目的,LCG适用于大多数用例(模拟,游戏等),但由于此方法的可预测性,因此不适合加密使用。
答案 13 :(得分:1)
首先,你需要一个RNG。在Kotlin中,您目前需要使用平台特定的(没有内置的Kotlin)。对于JVM,它是java.util.Random
。您需要创建一个实例,然后调用pom.xml
。
答案 14 :(得分:1)
No need to use custom extension functions anymore. IntRange has a random()
extension function out-of-the-box now.
val randomNumber = (0..10).random()
答案 15 :(得分:0)
要在Kotlin中获取随机的整数,请使用以下方法:
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
希望这会有所帮助。
答案 16 :(得分:0)
您可以创建扩展功能:
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()
}
浮点数:
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
答案 17 :(得分:0)
完整的源代码。可以控制是否允许重复。
import kotlin.math.min
abstract class Random {
companion object {
fun string(length: Int, isUnique: Boolean = false): String {
if (0 == length) return ""
val alphabet: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9') // Add your set here.
if (isUnique) {
val limit = min(length, alphabet.count())
val set = mutableSetOf<Char>()
do { set.add(alphabet.random()) } while (set.count() != limit)
return set.joinToString("")
}
return List(length) { alphabet.random() }.joinToString("")
}
fun alphabet(length: Int, isUnique: Boolean = false): String {
if (0 == length) return ""
val alphabet = ('A'..'Z')
if (isUnique) {
val limit = min(length, alphabet.count())
val set = mutableSetOf<Char>()
do { set.add(alphabet.random()) } while (set.count() != limit)
return set.joinToString("")
}
return List(length) { alphabet.random() }.joinToString("")
}
}
}
答案 18 :(得分:0)
每当有一种情况需要生成密钥或mac地址(该密钥或mac地址是根据用户需求具有数字的十六进制数字),并且也要使用android和kotlin时,那么我下面的代码就可以帮助您:
private fun getRandomHexString(random: SecureRandom, numOfCharsToBePresentInTheHexString: Int): String {
val sb = StringBuilder()
while (sb.length < numOfCharsToBePresentInTheHexString) {
val randomNumber = random.nextInt()
val number = String.format("%08X", randomNumber)
sb.append(number)
}
return sb.toString()
}
答案 19 :(得分:0)
在科特林以下对我来说很好:
(fromNumber.rangeTo(toNumber)).random()
数字范围以变量fromNumber
开始,以变量toNumber
结尾。 fromNumber
和toNumber
也将包含在由此产生的随机数中。
答案 20 :(得分:-1)
成为超级骗子))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}