如何从数组中随机选择一个元素


94

我正在寻找从整数数组中随机选择数字的解决方案。

例如我有一个数组new int[]{1,2,3},如何随机选择一个数字?


提及

Answers:


182
public static int getRandom(int[] array) {
    int rnd = new Random().nextInt(array.length);
    return array[rnd];
}

2
是的,但是您必须说这generatorjava.util.Random
stivlo 2011年

25
我不会在Random()每次运行该函数时创建该函数:随机生成器应该具有历史记录。如果没有,那是非常可预测的。在这种情况下,这根本不是问题,但应该指出的array[(int)(System.currentTimeMillis() % array.length)]是,它与建议的解决方案一样好。
阿尔夫

4
@alf,与建议的解决方案相差甚远。new Random()尝试创建一个实例,该实例的种子与先前创建的种子不同Random。仅在短时间内调用该函数两次,您的方法就会彻底崩溃。
aioobe

1
@alf一些系统没有毫秒级精确时钟,如果发生以下情况,它可能会排除某些选择gcd(array.length,clockAccuracy)!=1
棘轮异常

3
我刚刚注意到一条通知,称我对该答案不满意-我一定是不小心点击了它;不幸的是,该界面不允许我撤消它(它说除非编辑答案,否则我无法更改我的投票...)。因此,对Chris Dennett表示歉意。
彼得·汉利

13

您可以使用Random生成器生成随机索引并返回该索引处的元素:

//initialization
Random generator = new Random();
int randomIndex = generator.nextInt(myArray.length);
return myArray[randomIndex];

9

如果要多次获得一个随机元素,则要确保随机数生成器仅初始化一次。

import java.util.Random;

public class RandArray {
    private int[] items = new int[]{1,2,3};

    private Random rand = new Random();

    public int getRandArrayElement(){
        return items[rand.nextInt(items.length)];
    }
}

如果要选择需要不可预测的随机数组元素,则应使用java.security.SecureRandom而不是Random。这样可以确保如果有人知道最后几个选秀权,那么他们在猜测下一个选秀权上将不会有优势。

如果要使用泛型从对象数组中选择随机数,则可以定义一个方法(字符串数组Random元素中的 Source Avinash R):

import java.util.Random;

public class RandArray {
    private static Random rand = new Random();

    private static <T> T randomFrom(T... items) { 
         return items[rand.nextInt(items.length)]; 
    }
}

3

用于java.util.Random生成介于0和数组length:之间的随机数random_number,然后使用随机数获取整数:array[random_number]


3

使用随机类:

int getRandomNumber(int[] arr)
{
  return arr[(new Random()).nextInt(arr.length)];
}

2

您也可以使用

public static int getRandom(int[] array) {
    int rnd = (int)(Math.random()*array.length);
    return array[rnd];
}

Math.random()返回double介于0.0(包含)到1.0(不含)之间

将此乘以可array.length得出double介于0.0(含)和array.length(不含)之间的信息

强制转换为int会舍入为您和之间0(包括)和array.length-1(包括)之间的整数


Math.random()返回一个double而不是一个int。如果必须有本来只是两个可能的值0和1
阿克沙伊R.

1

由于您具有Java 8,因此另一个解决方案是使用Stream API。

new Random().ints(1, 500).limit(500).forEach(p -> System.out.println(list[p]));

哪里1是生成的最低int(含),500是最高(不含)。limit表示您的信息流长度为500。

 int[] list = new int[] {1,2,3,4,5,6};
 new Random().ints(0, list.length).limit(10).forEach(p -> System.out.println(list[p])); 

随机来自java.util包装。



0

Java在java.util包中有一个Random类。使用它,您可以执行以下操作:

Random rnd = new Random();
int randomNumberFromArray = array[rnd.nextInt(3)];

希望这可以帮助!


0
package workouts;

import java.util.Random;

/**
 *
 * @author Muthu
 */
public class RandomGenerator {
    public static void main(String[] args) {
     for(int i=0;i<5;i++){
         rndFunc();
     } 
    }
     public static void rndFunc(){
           int[]a= new int[]{1,2,3};
           Random rnd= new Random();
           System.out.println(a[rnd.nextInt(a.length)]);
       }
}

0

您也可以尝试这种方法。

public static <E> E[] pickRandom_(int n,E ...item) {
        List<E> copy = Arrays.asList(item);
        Collections.shuffle(copy);
        if (copy.size() > n) {
            return (E[]) copy.subList(0, n).toArray();
        } else {
            return (E[]) copy.toArray();
        }

    }

因此,您可以对具有O(nlogn)时间复杂性的列表进行混洗,即使使用OP询问的问题可以通过O(1)时间复杂性和O(1)内存来解决,也可以使用两倍于初始数组的三倍的内存来复制它的副本两次?
Jaroslaw Pawlak,

是的,您是对的,最好在时间和空间上保持不变。
拉维·萨帕里亚

0
package io.github.baijifeilong.tmp;

import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Stream;

/**
 * Created by BaiJiFeiLong@gmail.com at 2019/1/3 下午7:34
 */
public class Bar {
    public static void main(String[] args) {
        Stream.generate(() -> null).limit(10).forEach($ -> {
            System.out.println(new String[]{"hello", "world"}[ThreadLocalRandom.current().nextInt(2)]);
        });
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.