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

101

Я ищу решение для случайного выбора числа из целочисленного массива.

Например, у меня есть массив new int[]{1,2,3}, как я могу выбрать число случайным образом?

BreakHead
источник
Обратитесь к этому
Митхун Сасидхаран

Ответы:

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]

Джеймс Сюй
источник
3

Используйте класс Random :

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

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

Decden
источник
-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)]);
        });
    }
}
BaiJiFeiLong
источник