可以返回2个参数之间的随机整数的通用方法,例如ruby与rand(0..n)
。
有什么建议吗?
可以返回2个参数之间的随机整数的通用方法,例如ruby与rand(0..n)
。
有什么建议吗?
Answers:
我的建议是一个扩展的功能IntRange创建这样的随机量:(0..10).random()
从1.3开始,Kotlin带有自己的多平台随机数发生器。在此KEEP中对此进行了描述。下面描述的扩展现在是Kotlin标准库的一部分,只需像这样使用它:
val rnds = (0..10).random()
在1.3之前,我们在JVM上使用Random
,甚至ThreadLocalRandom
在JDK> 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和其他变体
对于不允许使用的kotlinjs和其他用例java.util.Random
,请参见此替代方法。
另外,请参阅此答案以了解我的建议。它还包括用于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
您可以创建类似于的扩展函数,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
我对随机字符的其他答案的可能变化
为了获得random 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()
或利用Java Random
val random2 = Random().nextInt(10) + 1
从1.3版本开始,标准库提供的随机量多平台支持,看到这个答案。
如果您使用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()
没有标准方法可以执行此操作,但是您可以使用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]
Kotlin标准库不提供随机数生成器API。如果您不在多平台项目中,则最好使用平台api (问题的所有其他答案都讨论此解决方案)。
但是,如果您处于多平台环境中,最好的解决方案是在纯Kotlin中自己实现随机,以在平台之间共享相同的随机数生成器。开发和测试更加简单。
为了在我的个人项目中回答这个问题,我实现了一个纯Kotlin 线性同余生成器。LCG是的算法java.util.Random
。如果要使用它,请遵循此链接:https :
//gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
我nextInt(range: IntRange)
为您实现的目的;)。
请注意我的目的,LCG适用于大多数用例(模拟,游戏等),但由于此方法的可预测性,因此不适合密码使用。
如果要选择的数字不是连续的,则可以使用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中获得随机的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()
}
来回浮动值:
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
完整的源代码。可以控制是否允许重复。
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("")
}
}
}
每当有需要生成密钥或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()
}
要超级傻瓜))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}
java.util.Random
?