Как случайным образом выбрать элемент из массива


Ответы:


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

2
да, но вы должны сказать, что generatorэто экземплярjava.util.Random
Стивло

26
Я бы не стал создавать Random()каждый раз, когда вы запускаете функцию: у случайного генератора должна быть история. Если нет, это очень предсказуемо. В данном случае это не проблема, но следует отметить, что array[(int)(System.currentTimeMillis() % array.length)]ничуть не хуже предлагаемого решения.
alf 09

7
@alf, что далеко не так хорошо, как предлагаемое решение. new Random()пытается создать экземпляр, который имеет другое начальное значение, чем любое ранее созданное Random. Ваш подход ужасно сломается, если вы вызовете функцию дважды за короткое время.
aioobe 09

1
@alf в некоторых системах нет часов с точностью до миллисекунды, что может помешать некоторым опциям, еслиgcd(array.length,clockAccuracy)!=1
храповой урод

3
Я только что заметил уведомление о том, что я проголосовал против этого ответа - должно быть, я нажал на него случайно; к сожалению, интерфейс не позволяет мне отменить его (он говорит, что я не могу изменить свой голос, пока ответ не будет отредактирован ...). Итак, извинения перед Крисом Деннетом.
Питер Хэнли

13

Вы можете использовать генератор случайных чисел для генерации случайного индекса и возврата элемента по этому индексу:

//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. Это гарантирует, что, если кто-то знает несколько последних выборов, у него не будет преимущества при угадывании следующего.

Если вы хотите выбрать случайное число из массива объектов с помощью универсальных шаблонов, вы можете определить метод для этого (источник 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 до длины массива : random_number, а затем используйте случайное число для получения целого числа:array[random_number]



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.
Акшай Р.

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

Вы также можете попробовать этот подход ..

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)временной сложностью, делаете его копию дважды, используя в общей сложности в 3 раза больше памяти, чем исходный массив, даже если проблема, о которой спрашивал OP, может быть решена с O(1)временной сложностью и O(1)памятью ...?
Ярослав Павляк

да, вы правы, это было лучше с постоянной временной и пространственной сложностью.
Рави Сапария

-1

Java имеет класс Random в пакете java.util. С его помощью вы можете сделать следующее:

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

Надеюсь это поможет!


-1
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)]);
       }
}

-1
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)]);
        });
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.