一个泛型方法,可以返回两个参数之间的随机整数,就像ruby对rand(0..n)所做的那样。

任何建议吗?


当前回答

基于@s1m0nw1的优秀答案,我做了以下更改。

(0..n)在Kotlin中表示包含 (0到n)在Kotlin中表示独占 为Random实例使用单例对象(可选)

代码:

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())
                }
        )
    }

其他回答

你可以创建一个类似于java.util.Random.nextInt(int)的扩展函数,但它的边界是一个inrange而不是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, 8, or 9

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

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

现在你可以像在Ruby中一样获得一个随机整数,而不需要自己首先声明一个随机实例:

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

在from(含)和to(不含)之间生成一个随机整数

import java.util.Random

val random = Random()

fun rand(from: Int, to: Int) : Int {
    return random.nextInt(to - from) + from
}

实现s1m0nw1的答案的另一种方法是通过变量访问它。这并不是说它更有效率,而是它使你不必输入()。

val ClosedRange<Int>.random: Int
    get() = Random().nextInt((endInclusive + 1) - start) +  start 

现在它可以被这样访问

(1..10).random

在[1,10]范围内的随机示例

val random1 = (0..10).shuffled().last()

或者使用Java Random

val random2 = Random().nextInt(10) + 1

从kotlin 1.2开始,您可以这样写:

(1 . . 3) .shuffled () .last ()

只要注意它是大O(n),但对于一个小列表(特别是唯一值),它是可以的:D