【问题标题】:How can I choose a random element from an ArrayList if it changes size?如果 ArrayList 改变大小,我如何从它中选择一个随机元素?
【发布时间】:2019-05-11 13:00:50
【问题描述】:

在我的代码中,“count0”、“count1”和“count2”接收随机值,“totalCount”是它们的总和。这里我已经简化了。

使用此代码,我可以选择 ArrayList 的随机元素,但如果例如“count0”等于 0,它将不仅在第一次而且每次迭代时都会从 ArrayList 中删除索引 0,如果发生这种情况会导致错误。 这个想法是如何从食品储藏室中随机选择成分,当一种用完时,你仍然可以从其余的中选择。

感谢您的帮助 =)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;

public class RndNumArray {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        int totalCount=4, count0=1, count1=1, count2=2;
        Random rnd = new Random();
        ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(0, 1, 2));

        while(totalCount > 0){

            int rand = rnd.nextInt(numbers.size());
            int num = numbers.get(rand);
            if (num == 0) {
                count0--;
                if (ccount0 == 0) {
                    numbers.remove(0);
                }
            }
            if (num == 1) {
                count1--;
                if (count1 == 0) {
                    numbers.remove(1);
                }
            }
            if (num == 2) {
                count2--;
                if (count2 == 0) {
                    numbers.remove(2);
                }
            }
            totalCount--;
            System.out.println(num);
        }
    }    
}

【问题讨论】:

  • 请注意,numbers.remove(0); 的意思不是“删除值 0”,而是“删除索引 0 处的元素”(因为 remove(int)remove(Object) 更专业)。因此,您需要使用 remove(Integer.valueOf(0)) 等 - 如果您删除一个元素,则所有后续元素的索引都会减小,因此如果您的列表仅包含 2 个元素,remove(2) 将不起作用。
  • 你可能过于复杂了。您能否展示并解释您的预期输出计数 0-2 的示例?
  • 您可以使用MapKey 可以是项目,Value 可以是项目数。

标签: java arrays arraylist random collections


【解决方案1】:

谢谢,伙计们。你们太棒了。 我会尝试你所有的建议,但我想出了一个可行的解决方案。我没有从列表中删除项目,而是为它们提供了一个值,我将使用 do-while 来控制,以便您只选择可用的项目。

我的代码是对冒烟问题(线程和同步)的修改。在我的代码中,每个吸烟者都有一定数量的雪茄,并且可以在其余人之前完成,因此代理人不必为他放置原料。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;

public class RndNumArray {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

    int totalCount=4, count0=1, count1=1, count2=2;
    Random rnd = new Random();
    ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(0, 1, 2));

    while(totalCount>0){
        int rand;
        int num;

        do{
        rand = rnd.nextInt(numbers.size());
        num = numbers.get(rand);
        } while(num==3);

        if (num == 0) {
            count0--;
            if (ccount0 == 0) {
                numbers.set(0,3);
            }
        }
        if (num == 1) {
            count1--;
            if (count1 == 0) {
                numbers.set(1,3);
            }
        }
        if (num == 2) {
            count2--;
            if (count2 == 0) {
                numbers.set(2,3);
            }
        }
        totalCount--;
        System.out.println(num);
    }
    }    
}

【讨论】:

    【解决方案2】:

    使用两个列表计数(您有多少产品)和数字(产品编号):

    public static void main(final String[] args)
    {
        final int totalCount = 4;
        final Random rnd = new Random(); 
        final List<Integer> numbers = new ArrayList<>(Arrays.asList(0, 1, 2));
        final List<Integer> counts = new ArrayList<>(Arrays.asList(1, 1, 2));
    
        for (int i = 1; i < totalCount; i++)
        {
            final int rand = rnd.nextInt(numbers.size());
            final int num = numbers.get(rand);
            int count = counts.get(rand);
            count--;
            if (count < 1)
            {
                numbers.remove(rand);
                counts.remove(rand);
            }else
            {
                counts.set(rand, count);
            }
            System.out.println(num);
        }
    }
    

    或者,如果您的产品编号始终为 0、1、2、3,您可以删除编号列表...

    【讨论】:

      猜你喜欢
      • 2011-06-08
      • 1970-01-01
      • 2013-04-26
      • 1970-01-01
      • 2014-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      相关资源
      最近更新 更多