Как генерировать случайные целые числа в определенном диапазоне в Java?

2845

Как создать случайное значение int в определенном диапазоне?

Я пробовал следующее, но это не работает:

Попытка 1:

randomNum = minimum + (int)(Math.random() * maximum);
// Bug: 'randomNum' can be bigger than 'maximum'.

Попытка 2:

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;
// Bug: 'randomNum' can be smaller than 'minimum'.
Теги:
integer
random

61 ответ

3179

В Java 1.7 или более поздней версии стандартный способ сделать это выглядит следующим образом:

import java.util.concurrent.ThreadLocalRandom;

// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);

См. Соответствующий JavaDoc. Преимущество такого подхода состоит в том, что не нужно явно инициализировать экземпляр java.util.Random, который может быть источником путаницы и ошибки при неправильном использовании.

Однако, наоборот, нет возможности явно установить семя, поэтому может быть трудно воспроизвести результаты в ситуациях, когда это полезно, например, при тестировании или сохранении игровых состояний или аналогичных. В таких ситуациях может использоваться метод pre-Java 1.7, показанный ниже.

До Java 1.7 стандартный способ сделать это выглядит следующим образом:

import java.util.Random;

/**
 * Returns a pseudo-random number between min and max, inclusive.
 * The difference between min and max can be at most
 * <code>Integer.MAX_VALUE - 1</code>.
 *
 * @param min Minimum value
 * @param max Maximum value.  Must be greater than min.
 * @return Integer between min and max, inclusive.
 * @see java.util.Random#nextInt(int)
 */
public static int randInt(int min, int max) {

    // NOTE: This will (intentionally) not run as written so that folks
    // copy-pasting have to think about how to initialize their
    // Random instance.  Initialization of the Random instance is outside
    // the main scope of the question, but some decent options are to have
    // a field that is initialized once and then re-used as needed or to
    // use ThreadLocalRandom (if using at least Java 1.7).
    // 
    // In particular, do NOT do 'Random rand = new Random()' here or you
    // will get not very good / not very random results.
    Random rand;

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
}

См. Соответствующий JavaDoc. На практике класс java.util.Random часто предпочтительнее java.lang.Math.random().

В частности, нет необходимости повторно изобретать колесо генерации случайных целых чисел, когда для выполнения задачи имеется простой API в стандартной библиотеке.

  • 36
    Для вызовов, где max значение - Integer.MAX_VALUE возможно переполнение, что приводит к исключению java.lang.IllegalArgumentException . Вы можете попробовать с: randInt(0, Integer.MAX_VALUE) . Кроме того, если nextInt((max-min) + 1) возвращает самое высокое значение (довольно редко, я полагаю), оно не переполнится снова (предположим, что min и max являются достаточно высокими значениями)? Как бороться с такими ситуациями?
  • 7
    Это не работает долго
Показать ещё 14 комментариев
1280

Обратите внимание, что этот подход более предвзятый и менее эффективный, чем подход nextInt, https://stackoverflow.com/questions/738629/math-random-versus-random-nextintint

Один стандартный шаблон для этого:

Min + (int)(Math.random() * ((Max - Min) + 1))

Функция библиотеки Java Math Math.random() генерирует двойное значение в диапазоне [0,1). Обратите внимание, что этот диапазон не включает 1.

Чтобы сначала получить определенный диапазон значений, вам нужно умножить на величину диапазона значений, которые вы хотите покрыть.

Math.random() * ( Max - Min )

Это возвращает значение в диапазоне [0,Max-Min), где "Макс-Мин" не включается.

Например, если вы хотите [5,10), вам нужно покрыть пять целых значений, чтобы вы использовали

Math.random() * 5

Это вернет значение в диапазоне [0,5), где 5 не включено.

Теперь вам нужно сдвинуть этот диапазон до диапазона, на который вы нацеливаетесь. Вы делаете это, добавляя значение Min.

Min + (Math.random() * (Max - Min))

Теперь вы получите значение в диапазоне [Min,Max). Следуя нашему примеру, это означает [5,10):

5 + (Math.random() * (10 - 5))

Но это все еще не включает Max и вы получаете двойное значение. Чтобы получить значение Max, вам нужно добавить 1 к вашему параметру диапазона (Max - Min) а затем усечь десятичную часть, выполнив кастинг в int. Это достигается посредством:

Min + (int)(Math.random() * ((Max - Min) + 1))

И вот он у вас есть. Случайное целочисленное значение в диапазоне [Min,Max] или в примере [5,10]:

5 + (int)(Math.random() * ((10 - 5) + 1))
  • 76
    В документации Sun явно сказано, что вам лучше использовать Random (), если вам нужен int вместо Math.random (), который выдает double.
  • 6
    Это на самом деле предвзято по сравнению с методами nextInt stackoverflow.com/a/738651/360211
302

Использование:

Random ran = new Random();
int x = ran.nextInt(6) + 5;

Целое число x теперь является случайным числом, которое имеет возможный результат 5-10.

124

Использование:

minimum + rn.nextInt(maxValue - minvalue + 1)
108

С они внедрили метод ints(int randomNumberOrigin, int randomNumberBound) в классе Random.

Например, если вы хотите сгенерировать пять случайных целых чисел (или один) в диапазоне [0, 10], просто выполните:

Random r = new Random();
int[] fiveRandomNumbers = r.ints(5, 0, 11).toArray();
int randomNumber = r.ints(1, 0, 11).findFirst().getAsInt();

Первый параметр указывает только размер генерируемого IntStream (который является перегруженным методом того, который создает неограниченный IntStream).

Если вам нужно выполнить несколько отдельных вызовов, вы можете создать бесконечный примитивный итератор из потока:

public final class IntRandomNumberGenerator {

    private PrimitiveIterator.OfInt randomIterator;

    /**
     * Initialize a new random number generator that generates
     * random numbers in the range [min, max]
     * @param min - the min value (inclusive)
     * @param max - the max value (inclusive)
     */
    public IntRandomNumberGenerator(int min, int max) {
        randomIterator = new Random().ints(min, max + 1).iterator();
    }

    /**
     * Returns a random number in the range (min, max)
     * @return a random number in the range (min, max)
     */
    public int nextInt() {
        return randomIterator.nextInt();
    }
}

Вы также можете сделать это для значений double и long.

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

  • 1
    Я бы посоветовал вам создать экземпляр randomIterator только один раз. См. Грег Кейс комментирует его собственный ответ.
  • 0
    если вы можете, можете ли вы объяснить, каково значение streamSize - первый параметр этого метода задан streamSize !=0 . Какая разница, если streamSize 1/2 / n?
95

Достаточно небольшой модификации вашего первого решения.

Random rand = new Random();
randomNum = minimum + rand.nextInt((maximum - minimum) + 1);

Подробнее о реализации Random

  • 0
    Для минимума <= значение <максимум, я сделал то же самое с Math: randomNum = минимум + (int) (Math.random () * (максимум-минимум)); но на кастинге не очень приятно смотреть;)
92

Вы можете отредактировать свой второй пример кода, чтобы:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;
58

ThreadLocalRandom эквивалент класса java.util.Random для многопоточной среды. Генерация случайного числа выполняется локально в каждом из потоков. Таким образом, мы имеем лучшую производительность за счет сокращения конфликтов.

int rand = ThreadLocalRandom.current().nextInt(x,y);

x, y - интервалы, например. (1,10)

56

Класс Math.Random в Java основан на 0. Итак, если вы напишете что-то вроде этого:

Random rand = new Random();
int x = rand.nextInt(10);

x будет находиться между 0-9 включительно.

Итак, учитывая следующий массив из 25 элементов, код для генерации случайного числа между 0 (базой массива) и array.length будет:

String[] i = new String[25];
Random rand = new Random();
int index = 0;

index = rand.nextInt( i.length );

Поскольку i.length вернет 25, nextInt( i.length ) вернет число между диапазоном 0-24. Другой вариант идет с Math.Random который работает одинаково.

index = (int) Math.floor(Math.random() * i.length);

Для лучшего понимания, ознакомьтесь с сообщениями форума Случайные интервалы (archive.org).

  • 0
    +1 для ссылки скриншота архива wayBackMachine, и ваш ответ по-прежнему полезен для получения "случайных" целых чисел в диапазоне.
  • 0
    Это сбивает с толку меня, почему вы создаете индекс до 0.
Показать ещё 2 комментария
43

Простите меня за брезгливость, но решение, предложенное большинством, т. min + rng.nextInt(max - min + 1)), кажется опасным из-за того, что:

  • rng.nextInt(n) не может достигнуть Integer.MAX_VALUE.
  • (max - min) может привести к переполнению, когда min отрицательный.

Убедительное решение вернет правильные результаты для любого min <= max внутри [ Integer.MIN_VALUE, Integer.MAX_VALUE ]. Рассмотрим следующую наивную реализацию:

int nextIntInRange(int min, int max, Random rng) {
   if (min > max) {
      throw new IllegalArgumentException("Cannot draw random int from invalid range [" + min + ", " + max + "].");
   }
   int diff = max - min;
   if (diff >= 0 && diff != Integer.MAX_VALUE) {
      return (min + rng.nextInt(diff + 1));
   }
   int i;
   do {
      i = rng.nextInt();
   } while (i < min || i > max);
   return i;
}

Хотя неэффективна, что вероятность успеха в while петля всегда будет 50% или выше.

  • 0
    Почему бы не создать исключение IllegalArgumentException, когда разница = Integer.MAX_VALUE? Тогда вам не нужен цикл while.
  • 3
    @mpkorstanje Эта реализация предназначена для работы с любыми значениями min <= max, даже если их разность равна или даже больше, чем MAX_VALUE. Выполнение цикла до достижения успеха в этом случае является общей схемой, гарантирующей равномерное распределение (если основной источник случайности является однородным). Random.nextInt (int) делает это внутренне, когда аргумент не является степенью 2.
27

Интересно, подходит ли какой-либо метод генерации случайных чисел, предоставленный библиотекой Apache Commons Math, для счета.

Например: RandomDataGenerator.nextInt или RandomDataGenerator.nextLong

25

Возьмем пример.

Предположим, что я хочу сгенерировать число между 5-10:

int max = 10;
int min = 5;
int diff = max - min;
Random rn = new Random();
int i = rn.nextInt(diff + 1);
i += min;
System.out.print("The Random Number is " + i);

Давайте поймем это...

Инициализируйте max с наивысшим значением и min с самым низким значением.

Теперь нам нужно определить, сколько возможных значений можно получить. Для этого примера это будет:

5, 6, 7, 8, 9, 10

Таким образом, это будет max - min + 1.

т.е. 10 - 5 + 1 = 6

Случайное число будет генерировать число от 0 до 5.

т.е. 0, 1, 2, 3, 4, 5

Добавление значения min к случайному числу приведет к:

5, 6, 7, 8, 9, 10

Следовательно, мы получаем желаемый диапазон.

23
 rand.nextInt((max+1) - min) + min;
19

Создайте случайное число для разности min и max с помощью метода nextint (n), а затем добавьте минимальное число в результат:

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);
19

Здесь полезный класс для генерации случайных ints в диапазоне с любой комбинацией включительно/исключительных границ:

import java.util.Random;

public class RandomRange extends Random {
    public int nextIncInc(int min, int max) {
        return nextInt(max - min + 1) + min;
    }

    public int nextExcInc(int min, int max) {
        return nextInt(max - min) + 1 + min;
    }

    public int nextExcExc(int min, int max) {
        return nextInt(max - min - 1) + 1 + min;
    }

    public int nextIncExc(int min, int max) {
        return nextInt(max - min) + min;
    }
}
17

Начиная с Java 7, вы больше не должны использовать Random. Для большинства применений генератором случайных чисел является ThreadLocalRandom.

Для пулов объединения fork и параллельных потоков используйте SplittableRandom.

Джошуа Блох. Эффективная Java. Третье издание.

Начиная с Java 8

Для пулов объединения fork и параллельных потоков используйте SplittableRandom который, как правило, быстрее, обладает лучшими статистическими независимыми и однородными свойствами по сравнению с Random.

Чтобы создать случайный int в диапазоне [0, 1_000]:

int n = new SplittableRandom().nextInt(0, 1_001);

Чтобы создать случайный массив int[100] значений в диапазоне [0, 1_000]:

int[] a = new SplittableRandom().ints(100, 0, 1_001).parallel().toArray();

Чтобы вернуть поток случайных значений:

IntStream stream = new SplittableRandom().ints(100, 0, 1_001);
  • 0
    Есть ли причина, по которой пример включает в себя .parallel() ? Мне кажется, что генерация 100 случайных чисел была бы слишком тривиальной, чтобы оправдать параллелизм.
  • 0
    @Johnbot Спасибо за комментарий, вы правы. Но основной причиной было показать API (конечно, разумный путь - это измерить производительность перед использованием parallel обработки). Кстати, для массива из 1_000_000 элементов parallel версия на моей машине была в 2 раза быстрее по сравнению с последовательной.
17

Эти методы могут быть удобны в использовании:

Этот метод возвращает случайное число между предоставленным минимальным и максимальным значением:

public static int getRandomNumberBetween(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt(max - min) + min;
    if (randomNumber == min) {
        // Since the random number is between the min and max values, simply add 1
        return min + 1;
    } else {
        return randomNumber;
    }
}

и этот метод вернет случайное число из предоставленного минимального и максимального значений (поэтому сгенерированное число также может быть минимальным или максимальным числом):

public static int getRandomNumberFrom(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt((max + 1) - min) + min;

    return randomNumber;
}
  • 0
    // Since the random number is between the min and max values, simply add 1 . Зачем? Мин не считается? Обычно диапазон составляет [min, max), где min включено, а max исключено. Неправильный ответ, проголосовал вниз.
  • 0
    @MaartenBodewes +1 добавлен, потому что getRandomNumberBetween генерирует случайное число, исключая предоставленные конечные точки.
Показать ещё 1 комментарий
17

В случае прокатки кости это будет случайное число от 1 до 6 (не от 0 до 6), поэтому:

face = 1 + randomNumbers.nextInt(6);
17
int random = minimum + Double.valueOf(Math.random()*(maximum-minimun)).intValue();

Или взгляните на RandomUtils из Apache Commons.

  • 0
    Это полезно, но остерегайтесь небольшого недостатка: сигнатуры методов выглядят следующим образом: nextDouble (double startInclusive, double endInclusive), но если вы загляните внутрь методов, endInclusive на самом деле должно быть endExclusive.
  • 0
    Double.valueOf(Math.random()*(maximum-minimun)).intValue() - довольно запутанный (и неэффективный) способ сказать (int)(Math.random()*(maximum-minimun))
Показать ещё 1 комментарий
16

Я нашел этот пример. Генерируйте случайные числа:


В этом примере генерируются случайные целые числа в определенном диапазоне.

import java.util.Random;

/** Generate random integers in a certain range. */
public final class RandomRange {

  public static final void main(String... aArgs){
    log("Generating random integers in the range 1..10.");

    int START = 1;
    int END = 10;
    Random random = new Random();
    for (int idx = 1; idx <= 10; ++idx){
      showRandomInteger(START, END, random);
    }

    log("Done.");
  }

  private static void showRandomInteger(int aStart, int aEnd, Random aRandom){
    if ( aStart > aEnd ) {
      throw new IllegalArgumentException("Start cannot exceed End.");
    }
    //get the range, casting to long to avoid overflow problems
    long range = (long)aEnd - (long)aStart + 1;
    // compute a fraction of the range, 0 <= frac < range
    long fraction = (long)(range * aRandom.nextDouble());
    int randomNumber =  (int)(fraction + aStart);    
    log("Generated : " + randomNumber);
  }

  private static void log(String aMessage){
    System.out.println(aMessage);
  }
} 

Пример выполнения этого класса:

Generating random integers in the range 1..10.
Generated : 9
Generated : 3
Generated : 3
Generated : 9
Generated : 4
Generated : 1
Generated : 3
Generated : 9
Generated : 10
Generated : 10
Done.
15

Вы можете добиться этого на Java 8:

Random random = new Random();

int max = 10;
int min = 5;
int totalNumber = 10;

IntStream stream = random.ints(totalNumber, min, max);
stream.forEach(System.out::println);
15
public static Random RANDOM = new Random(System.nanoTime());

public static final float random(final float pMin, final float pMax) {
    return pMin + RANDOM.nextFloat() * (pMax - pMin);
}
15

Когда вам нужно много случайных чисел, я не рекомендую класс Random в API. У этого есть только слишком маленький период. Вместо этого попробуйте Mersenne twister. Существует реализация Java.

14

Вот простой пример, который показывает, как генерировать случайное число из замкнутого диапазона [min, max], а min <= max is true

Вы можете использовать его как поле в классе дыр, также имея все методы Random.class в одном месте

Пример результатов:

RandomUtils random = new RandomUtils();
random.nextInt(0, 0); // returns 0
random.nextInt(10, 10); // returns 10
random.nextInt(-10, 10); // returns numbers from -10 to 10 (-10, -9....9, 10)
random.nextInt(10, -10); // throws assert

Источники:

import junit.framework.Assert;
import java.util.Random;

public class RandomUtils extends Random {

    /**
     * @param min generated value. Can't be > then max
     * @param max generated value
     * @return values in closed range [min, max].
     */
    public int nextInt(int min, int max) {
        Assert.assertFalse("min can't be > then max; values:[" + min + ", " + max + "]", min > max);
        if (min == max) {
            return max;
        }

        return nextInt(max - min + 1) + min;
    }
}
14

Просто используйте класс Random:

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);
  • 4
    Я не вижу здесь ничего нового, что не было опубликовано в бесчисленных предыдущих сообщениях.
14

Другой вариант - просто использовать Apache Commons:

import org.apache.commons.math.random.RandomData;
import org.apache.commons.math.random.RandomDataImpl;

public void method() {
    RandomData randomData = new RandomDataImpl();
    int number = randomData.nextInt(5, 10);
    // ...
 }
11

Лучше использовать SecureRandom, а не просто Random.

public static int generateRandomInteger(int min, int max) {
    SecureRandom rand = new SecureRandom();
    rand.setSeed(new Date().getTime());
    int randomNum = rand.nextInt((max - min) + 1) + min;
    return randomNum;
}
  • 1
    Это не так хорошо, потому что если он выполняется за одну и ту же миллисекунду, вы получите тот же номер, вам нужно поместить инициализацию rand и setSeet вне метода.
  • 0
    Да, вам нужен seed, но с использованием SecureRandom.
Показать ещё 4 комментария
11
private static Random random = new Random();    

public static int getRandomInt(int min, int max){
  return random.nextInt(max - min + 1) + min;
}

ИЛИ

public static int getRandomInt(Random random, int min, int max)
{
  return random.nextInt(max - min + 1) + min;
}
  • 0
    Если max и min велики, это вызывает проблемы переполнения и даст неверные результаты.
11

Если вы хотите попробовать ответ с наибольшим количеством голосов выше, вы можете просто использовать этот код:

public class Randomizer
{
    public static int generate(int min,int max)
    {
        return min + (int)(Math.random() * ((max - min) + 1));
    }

    public static void main(String[] args)
    {
        System.out.println(Randomizer.generate(0,10));
    }
}

Это просто чисто и просто.

  • 1
    Это могло быть редактированием другого примера, теперь это просто вопиющая копия репутации. Указание «ответа большинством голосов» также не очень прямое, оно может измениться.
  • 0
    Это верно @MaartenBodewes. Когда я написал этот ответ, ответ с большинством голосов все еще был написан в виде алгоритмического решения. Теперь решение выше сильно изменилось, и теперь этот ответ выглядел как подражатель.
10
rand.nextInt((max+1) - min) + min;

Это прекрасно работает.

8
import java.util.Random; 

public class RandomUtil {
    // Declare as class variable so that it is not re-seeded every call
    private static Random random = new Random();

    /**
     * Returns a psuedo-random number between min and max (both inclusive)
     * @param min Minimim value
     * @param max Maximim value. Must be greater than min.
     * @return Integer between min and max (both inclusive)
     * @see java.util.Random#nextInt(int)
     */
    public static int nextInt(int min, int max) {
        // nextInt is normally exclusive of the top value,
        // so add 1 to make it inclusive
        return random.nextInt((max - min) + 1) + min;
    }
}
7

Вы можете использовать этот фрагмент кода, который решит вашу проблему:

Random r = new Random();
int myRandomNumber = 0;
myRandomNumber = r.nextInt(maxValue-minValue+1)+minValue;

Используйте myRandomNumber (который даст вам число в пределах диапазона).

6

Для генерации случайного числа "между двумя числами" используйте следующий код:

Random r = new Random();
int lowerBound = 1;
int upperBound = 11;
int result = r.nextInt(upperBound-lowerBound) + lowerBound;

Это дает вам случайное число между 1 (включительно) и 11 (исключая), поэтому инициализируйте значение upperBound, добавив 1. например, если вы хотите сгенерировать случайное число от 1 до 10, тогда инициализируйте номер верхнего номера с помощью 11 вместо от 10.

6

Я использую это:

 /**
   * @param min - The minimum.
   * @param max - The maximum.
   * @return A random double between these numbers (inclusive the minimum and maximum).
   */
 public static double getRandom(double min, double max) {
   return (Math.random() * (max+1-min)) + min;
 }

вы можете отправить его в Integer, если хотите. Надеюсь, это поможет:)

  • 0
    Эта функция выдает одно и то же число снова и снова. В моем случае это было: 2147483647
  • 0
    Fail: у вас есть функция, которая требует двойного, а затем выполнить + 1? Это, безусловно, идет вразрез с принципом наименьшего удивления. Что произойдет, если вы используете min = 0.1 и max = 0.2?
Показать ещё 1 комментарий
6

Вы можете сделать что-то вроде этого:

import java.awt.*;
import java.io.*;
import java.util.*;
import java.math.*;

public class Test {

    public static void main(String[] args) {
        int first, second;

        Scanner myScanner = new Scanner(System.in);

        System.out.println("Enter first integer: ");
        int numOne;
        numOne = myScanner.nextInt();
        System.out.println("You have keyed in " + numOne);

        System.out.println("Enter second integer: ");
        int numTwo;
        numTwo = myScanner.nextInt();
        System.out.println("You have keyed in " + numTwo);

        Random generator = new Random();
        int num = (int)(Math.random()*numTwo);
        System.out.println("Random number: " + ((num>numOne)?num:numOne+num));
    }
}
6

Я просто укажу, что не так с решениями, поставленными вопросом, и почему ошибки.

Решение 1:

randomNum = minimum + (int)(Math.random()*maximum); 

Проблема: randomNum присваивается значениям, большим, чем максимум.

Пояснение: Предположим, что наш минимум 5, и ваш максимум 10. Любое значение от Math.random() больше чем 0.6 сделает выражение оценки до 6 или выше, и добавление 5 делает его больше, чем 10 (ваш максимум). Проблема в том, что вы умножаете случайное число на максимум (который генерирует число, почти такое же большое, как максимум), а затем добавляя минимум. Если минимум равен 1, это неверно. Вы должны переключиться на, как указано в других ответах.

randomNum = minimum + (int)(Math.random()*(maximum-minimum+1))

+1, потому что Math.random() никогда не вернет 1.0.

Решение 2:

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;

Ваша проблема в том, что "%" может возвращать отрицательное число, если первый член меньше 0. Так как rn.nextInt() возвращает отрицательные значения с ~ 50% шанс, вы также не получите ожидаемого результата.Р >

Это было, однако, почти идеально. Вы просто должны были выглядеть немного дальше вниз по Javadoc, nextInt (Int N). Используя этот метод, выполните

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt(n);
randomNum =  minimum + i;

Также вернет желаемый результат.

  • 1
    % имеет еще большую проблему смещения распределения. Недавно я написал об этом в блоге: jaroslawpawlak.wordpress.com/2014/10/11/…
5

Другой подход с использованием Java 8 IntStream и Collections.shuffle

import java.util.stream.IntStream;
import java.util.ArrayList;
import java.util.Collections;

public class Main {

    public static void main(String[] args) {

        IntStream range = IntStream.rangeClosed(5,10);
        ArrayList<Integer> ls =  new ArrayList<Integer>();

        //populate the ArrayList
        range.forEach(i -> ls.add(new Integer(i)) );

        //perform a random shuffle  using the Collections Fisher-Yates shuffle
        Collections.shuffle(ls);
        System.out.println(ls);
    }
}

Эквивалент в Scala

import scala.util.Random

object RandomRange extends App{
  val x =  Random.shuffle(5 to 10)
    println(x)
}
  • 0
    Ницца. Вы можете использовать List<Integer> ls = range.boxed().collect(Collectors.toList());
  • 0
    new Integer (i) также был избыточным, но он все равно удаляется кодом из моего предыдущего комментария.
Показать ещё 1 комментарий
5

Вы можете использовать

RandomStringUtils.randomNumeric(int count)

который также относится к апасам.

4
import java.util.Random;

public class RandomSSNTest {

    public static void main(String args[]) {
        generateDummySSNNumber();
    }


    //831-33-6049
    public static void generateDummySSNNumber() {
        Random random = new Random();

        int id1 = random.nextInt(1000);//3
        int id2 = random.nextInt(100);//2
        int id3 = random.nextInt(10000);//4

        System.out.print((id1+"-"+id2+"-"+id3));
    }

}
  • 1
    Объяснение будет в порядке.
4

Я имею в виду линейную нормализацию порожденных случайных чисел в желаемый диапазон, используя следующее. Пусть x - случайное число, a и b - минимальный и максимальный диапазон искомого нормированного числа.

Затем ниже это просто очень простой код для проверки диапазона, создаваемого линейным отображением.

public static void main(String[] args) {
    int a = 100;
    int b = 1000;
    int lowest = b;
    int highest = a;
    int count = 100000;
    Random random = new Random();
    for (int i = 0; i < count; i++) {
        int nextNumber = (int) ((Math.abs(random.nextDouble()) * (b - a))) + a;
        if (nextNumber < a || nextNumber > b) {
            System.err.println("number not in range :" + nextNumber);
        }
        else {
            System.out.println(nextNumber);
        }
        if (nextNumber < lowest) {
            lowest = nextNumber;
        }
        if (nextNumber > highest) {
            highest = nextNumber;
        }
    }
    System.out.println("Produced " + count + " numbers from " + lowest
            + " to " + highest);
}
4

Я просто генерирую случайное число, используя Math.random() и умножаю его на большое число, скажем, 10000. Таким образом, я получаю число от 0 до 10000 и вызываю это число i. Теперь, если мне нужны числа между (x, y), выполните следующие действия:

i = x + (i % (y - x));

Итак, все i - числа между x и y.

Чтобы удалить предубеждение, указанное в комментариях, вместо того, чтобы умножить его на 10000 (или большое число), умножьте его на (yx).

3

Я слишком ленив, чтобы прочитать все ответы, чтобы проверить, что кто-то еще предложил это, но не должен делать следующее изменение в попытке 1 выполнить работу -

randomNum = minimum + (int)(Math.random() * (maximum - minimum) );

Проверьте это для рабочего кода

3

Ниже приведен еще один пример использования Random и forEach

int firstNum = 20;//Inclusive
int lastNum = 50;//Exclusive
int streamSize = 10;
Random num = new Random().ints(10, 20, 50).forEach(System.out::println);
3

Это довольно простой ответ.

→ Предположим, вы хотите, чтобы диапазон между 0-9, 0 был минимальным, а 9 - макс. Функция внизу будет печатать что-либо между 0 и 9. Это же касается всех диапазонов.

public static void main(String[] args) {
    int b = randomNumberRange(0, 9);
    int d = randomNumberRange (100, 200);
    System.out.println("value of b is " + b);
    System.out.println("value of d is " + d);
}

public static int randomNumberRange(int min, int max) {
int n = (max + 1 - min) + min;
return (int) (Math.random() * n);
}
  • 0
    Это не выглядит правильно. В "int n = (max + 1 - min) + min; return (int) (Math.random () * n);" , n = max + 1, и вы просто создаете int в [0, max] вместо [min, max]. Это должно быть "int n = max + 1 - min; return (int) (Math.random () * n) + min;"
3

В приведенном ниже коде генерируется случайное число от 100 000 до 900 000. Этот код будет генерировать шестизначные значения. Я использую этот код для генерации шестизначного OTP.

Используйте import java.util.Random чтобы использовать этот случайный метод.

import java.util.Random;

// Six digits random number generation for OTP
Random rnd = new Random();
long longregisterOTP = 100000 + rnd.nextInt(900000);
System.out.println(longregisterOTP);
3

Я создал метод для получения уникального целого числа в заданном диапазоне.

/*
      * minNum is the minimum possible random number
      * maxNum is the maximum possible random number
      * numbersNeeded is the quantity of random number required
      * the give method provides you with unique random number between min & max range
*/
public static Set<Integer> getUniqueRandomNumbers( int minNum , int maxNum ,int numbersNeeded ){

    if(minNum >= maxNum)
        throw new IllegalArgumentException("maxNum must be greater than minNum");

    if(! (numbersNeeded > (maxNum - minNum + 1) ))
        throw new IllegalArgumentException("numberNeeded must be greater then difference b/w (max- min +1)");

    Random rng = new Random(); // Ideally just create one instance globally

    // Note: use LinkedHashSet to maintain insertion order
    Set<Integer> generated = new LinkedHashSet<Integer>();
    while (generated.size() < numbersNeeded)
    {
        Integer next = rng.nextInt((maxNum - minNum) + 1) + minNum;

        // As we're adding to a set, this will automatically do a containment check
        generated.add(next);
    }
    return generated;
}
3

Это приведет к списку случайных чисел с диапазоном (Min - Max) без дубликата.

generateRandomListNoDuplicate(1000, 8000, 500);

Добавьте этот метод.

private void generateRandomListNoDuplicate(int min, int max, int totalNoRequired) {
    Random rng = new Random();
    Set<Integer> generatedList = new LinkedHashSet<>();
    while (generatedList.size() < totalNoRequired) {
        Integer radnomInt = rng.nextInt(max - min + 1) + min;
        generatedList.add(radnomInt);
    }
}

Надеюсь, это поможет вам.

  • 0
    Это становится сложно, когда вы найдете большинство чисел в пределах диапазона; Есть более эффективные способы сделать это (например, генерировать случайное число с максимальным числом, равным количеству оставшихся элементов, и пропускать уже найденные числа. Как в действительности Бинго.
3

Вы можете использовать класс Random для генерации случайного числа, а затем использовать .nextInt(maxNumber) для генерации случайного числа. MaxNumber - это номер, который вы хотите получить при генерации случайного числа. Помните, однако, что класс Random дает вам цифры от 0 до maxNumber-1.

Random r = new Random();
int i = r.nextInt();

Другой способ сделать это - использовать класс Math.Random(), который многие классы в школах требуют от вас, потому что он более эффективен, и вам не нужно объявлять новый объект Random. Чтобы получить случайное число с помощью Math.Random(), введите:

Math.random() * (max - min) + min;
3

Я думаю, что этот код будет работать на него. Попробуйте следующее:

import java.util.Random;
public final class RandomNumber {

    public static final void main(String... aArgs) {
        log("Generating 10 random integers in range 1..10.");
        int START = 1;
        int END = 10;
        Random randomGenerator = new Random();
        for (int idx=1; idx<=10; ++idx) {

            // int randomInt=randomGenerator.nextInt(100);
            // log("Generated : " + randomInt);
            showRandomInteger(START,END,randomGenerator);
        }
        log("Done");
    }

    private static void log(String aMessage) {
        System.out.println(aMessage);
    }

    private static void showRandomInteger(int aStart, int aEnd, Random aRandom) {
        if (aStart > aEnd) {
            throw new IllegalArgumentException("Start cannot exceed End.");
        }
        long range = (long)aEnd - (long)aStart + 1;
        long fraction = (long) (range * aRandom.nextDouble());
        int randomNumber = (int) (fraction + aStart);
        log("Generated" + randomNumber);
    }
}
3

Один из моих друзей задал мне тот же вопрос в университете сегодня (его требования состояли в том, чтобы создать случайное число от 1 до -1). Поэтому я написал это, и до сих пор он отлично работает с моим тестированием. В идеале существует множество способов генерации случайных чисел с учетом диапазона. Попробуйте следующее:

Функции:

private static float getRandomNumberBetween(float numberOne, float numberTwo) throws Exception{

    if (numberOne == numberTwo){
        throw new Exception("Both the numbers can not be equal");
    }

    float rand = (float) Math.random();
    float highRange = Math.max(numberOne, numberTwo);
    float lowRange = Math.min(numberOne, numberTwo);

    float lowRand = (float) Math.floor(rand-1);
    float highRand = (float) Math.ceil(rand+1);

    float genRand = (highRange-lowRange)*((rand-lowRand)/(highRand-lowRand))+lowRange;

    return genRand;
}

Выполните следующие действия:

System.out.println( getRandomNumberBetween(1,-1));
  • 0
    Попробуйте другие диапазоны, ваш код не выдает одинаковые значения в данном диапазоне. numberOne = 3.5 и numberTwo = 7.2 выдают значения только в диапазоне 4.73..5.96.
2

Существует библиотека на https://sourceforge.net/projects/stochunit/ для обработки выбора диапазонов.

StochIntegerSelector randomIntegerSelector = new StochIntegerSelector();
randomIntegerSelector.setMin(-1);
randomIntegerSelector.setMax(1);
Integer selectInteger = randomIntegerSelector.selectInteger();

Он имеет краевое включение/исключение.

2
Random random = new Random();
  int max = 10;
  int min = 3;
int randomNum = random.nextInt(max) % (max - min + 1) + min;
  • 0
    Объяснение будет в порядке.
2

Простой способ генерации n случайных чисел между a и b например a = 90, b = 100, n = 20

Random r = new Random();
for(int i =0; i<20; i++){
    System.out.println(r.ints(90, 100).iterator().nextInt());
}

r.ints() возвращает IntStream и имеет несколько полезных методов, посмотрите на API.

2

Это простой способ сделать это.

import java.util.Random;
class Example{
    public static void main(String args[]){
        /*-To test-
        for(int i = 1 ;i<20 ; i++){
            System.out.print(randomnumber()+",");
        }
        */

        int randomnumber = randomnumber();

    }

    public static int randomnumber(){
        Random rand = new Random();
        int randomNum = rand.nextInt(6) + 5;

        return randomNum;
    }
}

В нем 5 - начальная точка случайных чисел. 6 - диапазон, включающий номер 5.

2

Большинство приведенных выше предложений не учитывают "переполнение", например: min = Integer.MIN_VALUE, max = 100. Один из правильных подходов, который я до сих пор:

final long mod = max- min + 1L;
final int next = (int) (Math.abs(rand.nextLong() % mod) + min);
  • 0
    Создание защитных операторов (если значение> другое значение, а затем исключение) также должно работать (при условии, что диапазон не установлен пользовательским / системным вводом).
2

Случайное число из диапазона [мин..макс] включительно:

int randomFromMinToMaxInclusive = ThreadLocalRandom.current()
        .nextInt(min, max + 1);
2

Попробуйте использовать класс org.apache.commons.lang.RandomStringUtils. Да, он иногда дает повторяющееся число рядом, но он будет давать значение от 5 до 15:

    while (true)
    {
        int abc = Integer.valueOf(RandomStringUtils.randomNumeric(1));
        int cd = Integer.valueOf(RandomStringUtils.randomNumeric(2));
        if ((cd-abc) >= 5 && (cd-abc) <= 15)
        {
            System.out.println(cd-abc);
            break;
        }
    }
1

Если вы уже используете Commons Lang API 2.x или последнюю версию, тогда существует один класс для генерации случайных чисел RandomUtils.

public static int nextInt(int n)

Возвращает псевдослучайное равномерно распределенное значение int между 0 (включительно) и указанным значением (исключительным) из последовательности Math.random().

Параметры: n - указанное максимальное максимальное значение

int random = RandomUtils.nextInt(1000000);

Примечание. В RandomUtils есть много способов генерации случайных чисел

0
public static void main(String[] args) {

    Random ran = new Random();

    int min, max;
    Scanner sc = new Scanner(System.in);
    System.out.println("Enter min range:");
    min = sc.nextInt();
    System.out.println("Enter max range:");
    max = sc.nextInt();
    int num = ran.nextInt(min);
    int num1 = ran.nextInt(max);
    System.out.println("Random Number between given range is " + num1);

}
0

Использование потоков Java 8,

  • Пропустить initialCapacity - Сколько чисел
  • Передайте randomBound - от x до randomBound
  • Передать true/false для отсортированного или неактивного
  • Передайте новый объект Random()

 

public static List<Integer> generateNumbers(int initialCapacity, int randomBound, Boolean sorted, Random random) {

    List<Integer> numbers = random.ints(initialCapacity, 1, randomBound).boxed().collect(Collectors.toList());

    if (sorted)
        numbers.sort(null);

    return numbers;
}

Он генерирует числа из 1-Randombound в этом примере.

-2

Я не прочитал все это, но кто-нибудь сказал:

return (int)(Math.random()*(max-min+1)+min);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню