1. 概要

List などのコレクション構造で最も一般的な操作の1つは、含まれている要素からランダムなアイテムを取得することです。 簡単な操作ですが、実装がわかりにくい場合があります。

このチュートリアルでは、Kotlinを使用してさまざまなコンテキストでこれを行うためのいくつかの効率的な実装を紹介します。

2. 実装

リストからランダムなアイテムを選択する基本的な概念は、 List.get()メソッドを使用して特定の要素をフェッチするためのランダムなインデックスを生成することです。

2.1. 単一のランダムアイテム

前述したように、最初にランダムインデックスを生成してから、リストから要素を取得する必要があります。

fun randomElementFromGivenList() {
    val list = listOf(1, 2, 3, 4, 5)
    val randomIndex = Random.nextInt(list.size);
    val randomElement = list[randomIndex]

    // here we can use the selected element to print it for example
    println(randomElement)
}

Kotlin 1.3以降、リストからランダムなアイテムをフェッチするための組み込みメソッドがあります。

val list = listOf(1, 2, 3, 4, 5)
val randomElement = list.random()

2.2. シーケンスを持つランダム要素

シーケンスはコンテナです順序タイプ付き T 。 また、 map() filter()などの中間操作や、 count() find( )

Kotlin1.2以降で使用可能な組み込みのshuffled()メソッドを使用して、 Sequence タイプで使用可能な操作を利用して、リストからランダム要素を取得できます。

fun randomElementUsingSequences() {

    val list = listOf("one", "two", "three", "four", "five")
    val randomElement = list.asSequence().shuffled().find { true }

    // use the selected element or print it out
}

2.3. 複数のランダム要素

場合によっては、リストから複数のランダム要素を選択する必要があります。 結果として実行されるときに同じ要素を取得する必要がない場合は、それらをリスト内に保持できます。

fun randomElementsFromGivenList() {

    val list = listOf("one", "two", "three", "four", "five")
    val numberOfElements = 2

    val randomElements = list.asSequence().shuffled().take(numberOfElements).toList()

    // use the selected elements or print it out
}

実行ごとに異なる要素を常に期待している場合、またはすべてのアイテムをランダムに抽出する必要がある場合は、選択した要素をリストから削除する必要があります。

List タイプは不変であるため、元のリストを追加または更新できないことを覚えておくことが重要です。 したがって、要素を削除できるようにするには、MutableListを使用する必要があります。

val list = mutableListOf("one", "two", "three", "four", "five")
val randomElements = list.asSequence().shuffled().take(numberOfElements).toList()

list.removeIf { i -> randomElements.contains(i) }

2.4. マルチスレッド環境のランダム要素

マルチスレッドアプリケーションのRandomインスタンスにアクセスするプロセスごとに、異なる値を取得するようにする必要があります。 Kotlinにはこれを行うためのネイティブサポートがないため、JavaのThreadLocalRandomクラスを使用する必要があります。

fun randomElementMultithreaded() {

    val list = listOf("one", "two", "three", "four", "five")
    val randomIndex: Int = ThreadLocalRandom.current().nextInt(list.size)
    val randomElement = list[randomIndex]

    // use the selected element or print it out
}

3. 結論

この記事では、さまざまなユースケースとシナリオを考慮して、Kotlinのリストからランダムな要素を取得するためのいくつかの効率的な実装について説明しました。

いつものように、この記事の完全なコードは、GitHubから入手できます。