1. 序章

ランダムなList要素を選択することは非常に基本的な操作ですが、実装するのはそれほど明白ではありません。 この記事では、さまざまなコンテキストでこれを行う最も効率的な方法を示します。

2. ランダムなアイテムの選択

List インスタンスからランダムなアイテムを取得するには、ランダムなインデックス番号を生成し、 List.get()メソッドを使用してこの生成されたインデックス番号でアイテムをフェッチする必要があります。

ここで重要なのは、リストのサイズを超えるインデックスを使用してはならないことを覚えておくことです。

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

ランダムインデックスを選択するには、 Random.nextInt(int bound)メソッドを使用できます。

public void givenList_shouldReturnARandomElement() {
    List<Integer> givenList = Arrays.asList(1, 2, 3);
    Random rand = new Random();
    int randomElement = givenList.get(rand.nextInt(givenList.size()));
}

ランダムクラスの代わりに、静的メソッド Math.random()をいつでも使用して、リストサイズで乗算できます( Math.random()を生成しますDouble は0(包括的)から1(排他的)までのランダムな値なので、乗算後に intにキャストすることを忘れないでください)。

2.2. マルチスレッド環境でランダムインデックスを選択

単一のRandomクラスインスタンスを使用してマルチスレッドアプリケーションを作成する場合、このインスタンスにアクセスするすべてのプロセスに対して同じ値を選択する可能性があります。 専用のThreadLocalRandomクラスを使用すると、スレッドごとに新しいインスタンスをいつでも作成できます。

int randomElementIndex
  = ThreadLocalRandom.current().nextInt(listSize) % givenList.size();

2.3. 繰り返しのあるランダムアイテムを選択する

リストからいくつかの要素を選択したい場合があります。 それは非常に簡単です:

public void givenList_whenNumberElementsChosen_shouldReturnRandomElementsRepeat() {
    Random rand = new Random();
    List<String> givenList = Arrays.asList("one", "two", "three", "four");

    int numberOfElements = 2;

    for (int i = 0; i < numberOfElements; i++) {
        int randomIndex = rand.nextInt(givenList.size());
        String randomElement = givenList.get(randomIndex);
    }
}

2.4. 繰り返しのないランダムアイテムを選択する

ここでは、選択後に要素がリストから削除されていることを確認する必要があります。

public void givenList_whenNumberElementsChosen_shouldReturnRandomElementsNoRepeat() {
    Random rand = new Random();
    List<String> givenList = Lists.newArrayList("one", "two", "three", "four");

    int numberOfElements = 2;

    for (int i = 0; i < numberOfElements; i++) {
        int randomIndex = rand.nextInt(givenList.size());
        String randomElement = givenList.get(randomIndex);
        givenList.remove(randomIndex);
    }
}

2.5. ランダムシリーズを選択

ランダムな一連の要素を取得したい場合は、 Collectionsutilsクラスが便利です。

public void givenList_whenSeriesLengthChosen_shouldReturnRandomSeries() {
    List<Integer> givenList = Lists.newArrayList(1, 2, 3, 4, 5, 6);
    Collections.shuffle(givenList);

    int randomSeriesLength = 3;

    List<Integer> randomSeries = givenList.subList(0, randomSeriesLength);
}

3. 結論

この記事では、さまざまなシナリオリストインスタンスeからランダム要素をフェッチする最も効率的な方法について説明しました。

コード例はGitHubにあります。