很多時候,我們希望能夠隨機產生數字。在 Java 中,我們可以使用 Math.random 回傳一個在 0~1 之間的一個 double 數。
那麼,在 Kotlin 除了使用 Math.random 之外,還有沒有其他 Kotlin 內建的方法可以產生隨機數呢?
在這篇文章中,我將介紹四種不同的方式產生隨機變數。
1. Random
第一個要介紹的,當然是要從Standard Lib 的 Random 類介紹起。
Random 包含了許多以 next 開頭命名的函式,例如:nextInt()
, nextDouble()
, nextLong()
, nextFloat()
…
Random.nextInt()
//-2061105610Random.nextDouble()
//0.4966379730773498Random.nextLong()
//-4084004577217082135Random.nextFloat()
//0.8338781
另外, nextInt()
, nextDouble()
, nextLong()
包含兩個重載的版本。
一個是從 0 ~指定的值;另一個則是數值的範圍是自訂的。
nextInt()
- nextInt(until: Int)
- nextInt(from: Int, until: Int)
nextDouble()
- nextDouble(until: Double)
- nextDouble(from: Double, until: Double)
nextLong()
- nextLong(until: Long)
- nextLong(from: Long, until: Long)
2. IntRange.random
假設你需要產生一個在一段 Int 範圍內的任意數,除了使用前面提到的 Random.nextInt(from: Double, until:Double)
,有另一個方法更符合 Kotlin 風格,那就是使用 IntRange
的 random()
函式。
假設我想要產生一個在 0~100 之間的數字。我可以先定義一個 IntRange,然後使用 random 函式,來取得一個在範圍內的數字。
(0 .. 100).random()
//50
3. Iterable.shuffled
在 Kotlin 的 Iterable 類中,我們可以利用 shuffled()
函式將集合弄亂,然後隨機取一個值。實作 Iterable 的類,如 List, Set 或是前面介紹的 IntRange 都可以使用 shuffled 函式。
例如:
listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10).shuffled()
//[7, 6, 1, 5, 0, 9, 2, 10, 8, 4, 3]
接下來我們只需要隨機取一個元素即可。在 Collections 中,我們可以使用 first()
函式取得集合的第一個元素、 last()
函式取得最後一個元素或是直接使用 [ ]
取得特定位置的值。
listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10).shuffled().first()
//7listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10).shuffled().last()
//3listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10).shuffled()[2]
//1(0..10).shuffled().first()(0..10).shuffled()[5]
或是使用 random()
隨機取出一個值
listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10).shuffled().random()
IntRange.random, Collection.random
這邊介紹的 random()
函式與前面所介紹的 IntRange.random()
是不同的函示。
看了原始碼得知,其實這兩個 random()
函式,最終都是呼叫到 Random 的 nextInt()
。所以效果都是一樣的,可以依照自己的使用情境來選擇。
- IntRange.random
@SinceKotlin("1.3")
public fun IntRange.random(random: Random): Int {
try {
return random.nextInt(this)
} catch(e: IllegalArgumentException) {
throw NoSuchElementException(e.message)
}
}
- Collection.random
@SinceKotlin("1.3")
public fun <T> Collection<T>.random(random: Random): T {
if (isEmpty())
throw NoSuchElementException("Collection is empty.")
return elementAt(random.nextInt(size))
}
4. System.currentTimeMillis()
接下來的這個方法,比較奇耙一點,利用 System.currentTimeMillis() 取得以Million Second 表示的現在時間,接著取最後面的位數。
System.currentTimeMillis().toString().toCharArray().last().toInt()//Kotlin 1.5 以後
System.currentTimeMillis().toString().toCharArray().last().digitToInt()
不過嚴格說來,這個不是隨機產生出來的,只是看起來很像是隨機數而已。
結論
在 Kotlin 中,我們可以在 Random 類中使用 nextXXX 函式來隨機產生一組數字,並且還可以帶入起終值,讓產生的數值落在期待的區間中。
利用 Random 產生隨機數是屬於比較正規的方式,如果我們想要產生範圍內 Int 的隨機數,我們可以使用 IntRange 來建立一堆數字區間,並且使用 random()
隨機產生一個數字。
另外我們也可以使用任意的 List 、Set 來產生隨機數,這麼做的好處是,我們可以自行決定在集合裡面的數值是什麼,先使用 shuffled()
將集合函式弄亂,在隨機從集合裡面取得一個值。
最後,附上非正規的做法,我們也可以使用 System.currentTimeMillis()
來產生亂數,不過這樣可能不夠亂就是了。
本篇文章如果有幫助到你,請拍手👏鼓勵我吧~