Java – Get Random Item/Element From a List – Java – 从列表中获取随机项目/元素

最后修改: 2016年 10月 4日

1. Introduction

1.介绍

Picking a random List element is a very basic operation but not so obvious to implement. In this article, we’ll show the most efficient way of doing this in different contexts.

随机抽取一个List元素是一个非常基本的操作,但实现起来却不是那么明显。在这篇文章中,我们将展示在不同情况下最有效的操作方法。

2. Picking a Random Item/Items

2.随机选取一个/多个项目

In order to get a random item from a List instance, you need to generate a random index number and then fetch an item by this generated index number using List.get() method.

为了从List实例中获取一个随机项目,你需要生成一个随机的索引号,然后使用List.get()方法通过这个生成的索引号获取一个项目。

The key point here is to remember that you mustn’t use an index that exceeds your List’s size.

这里的关键点是要记住,你不能使用一个超过你的List大小的索引。

2.1. Single Random Item

2.1.单一随机项目

In order to select a random index, you can use Random.nextInt(int bound) method:

为了选择一个随机索引,你可以使用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()));
}

Instead of Random class, you can always use static method Math.random() and multiply it with list size (Math.random() generates Double random value between 0 (inclusive) and 1 (exclusive), so remember to cast it to int after multiplication).

你可以使用静态方法Math.random()来代替Random类,并与列表大小相乘(Math.random()生成Double随机值,介于0(包容)和1(排斥)之间,所以记得在乘法后将其铸为int)。

2.2. Select Random Index in Multithread Environment

2.2.在多线程环境中选择随机索引

When writing multithread applications using the single Random class instance, might result in picking same value for every process accessing this instance. We can always create a new instance per thread by using a dedicated ThreadLocalRandom class:

当编写多线程应用程序时,使用单一的Random类实例,可能会导致每个访问该实例的进程都采到相同的值。我们总是可以通过使用一个专门的ThreadLocalRandom类,为每个线程创建一个新的实例。

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

2.3. Select Random Items With Repetitions

2.3.选择具有重复性的随机项目

Sometimes you might want to pick few elements from a list. It is quite straightforward:

有时你可能想从一个列表中挑选几个元素。这是很直接的。

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. Select Random Items Without Repetitions

2.4.选择没有重复的随机项目

Here, you need to make sure that element is removed from the list after selection:

在这里,你需要确保该元素在选择后从列表中删除。

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. Select Random Series

2.5.选择随机系列

In case you would like to obtain random series of elements, Collections utils class might be handy:

如果你想获得随机系列的元素,Collections utils类可能很方便。

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. Conclusion

3.结论

In this article, we explored the most efficient way of fetching random elements from a List instance for different scenarios.

在这篇文章中,我们探索了从List实例中获取随机元素的最有效方式,以应对不同的场景.

Code examples can be found on GitHub.

代码实例可以在GitHub上找到。