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


В следующих методах есть ошибки, связанные с целочисленным переполнением:

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

// Bug: `randomNum` can be bigger than `maximum`.
Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;

// Bug: `randomNum` can be smaller than `minimum`.
3965
user42155 12 Дек 2008 в 21:20
Когда вам нужно много случайных чисел, я не рекомендую класс Random в API. У него слишком маленький период. Вместо этого попробуйте использовать Твистер Мерсенна. Существует реализация Java.
 – 
raupach
13 Дек 2008 в 13:18
35
Прежде чем публиковать новый ответ, учтите, что на этот вопрос уже есть более 65 ответов. Пожалуйста, убедитесь, что ваш ответ содержит информацию, которой нет среди существующих ответов.
 – 
janniks
3 Фев 2020 в 14:53

29 ответов

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

Для пулов вилочного соединения и параллельных потоки, используйте SplittableRandom.

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

Начиная с Явы 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);
30
Oleksandr Pyrohov 8 Фев 2019 в 11:56
Есть ли причина, по которой пример включает .parallel()? Мне кажется, что генерация 100 случайных чисел была бы слишком тривиальной, чтобы гарантировать параллелизм.
 – 
Johnbot
20 Июл 2018 в 09:29
Спасибо за комментарий, вы правы. Но главная причина заключалась в том, чтобы показать API (конечно, умный путь — измерить производительность перед использованием обработки parallel). Кстати, для массива из 1_000_000 элементов версия parallel на моей машине была в 2 раза быстрее по сравнению с последовательной.
 – 
Oleksandr Pyrohov
20 Июл 2018 в 11:35

Я нашел этот пример Создание случайных чисел:


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

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.
16
Martijn Pieters 8 Фев 2019 в 17:14
rand.nextInt((max+1) - min) + min;

Это нормально работает.

12
GAMITG 21 Апр 2016 в 09:01

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

minValue + rn.nextInt(maxValue - minValue + 1)
194
learner 30 Июн 2022 в 08:17

Чтобы сгенерировать случайное число «между двумя числами», используйте следующий код:

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

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

20
Martijn Pieters 8 Фев 2019 в 17:09
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();

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

19
Martijn Pieters 8 Фев 2019 в 17:11
Это полезно, но имейте в виду небольшой недостаток: сигнатуры методов выглядят так: nextDouble(double startInclusive, double endInclusive), но если вы заглянете внутрь методов, endInclusive на самом деле должен быть endExclusive.
 – 
zakmck
30 Янв 2015 в 12:27
Double.valueOf(Math.random()*(maximum-minimun)).intValue() — довольно запутанный (и неэффективный) способ сказать (int)(Math.random()*(maximum-minimun))
 – 
Holger
3 Июн 2016 в 12:47
1
Орфографическое несоответствие для минимального возвращаемого минимума + Double.valueOf(Math.random() * (максимум - минимум)).intValue();
 – 
Hrishikesh Mishra
26 Дек 2016 в 08:14

С помощью они представили метод 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. Я надеюсь, что это помогает! :)

181
Naman 2 Апр 2020 в 18:08
3
Я бы посоветовал вам создать экземпляр randomIterator только один раз. См. Комментарий Грега Кейса к его собственному ответу.
 – 
Naxos84
26 Фев 2018 в 10:13

Вы можете отредактировать свой второй пример кода следующим образом:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;
118
Bill the Lizard 8 Фев 2019 в 16:02

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

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

Дополнительные сведения о реализации Random

107
Martijn Pieters 8 Фев 2019 в 17:14
Для минимального <= значения < максимального я сделал то же самое с Math : randomNum = минимум + (int)(Math.random() * (максимум-минимум)); но приведение на самом деле не приятно видеть ;)
 – 
AxelH
8 Июл 2016 в 15:30
1
По крайней мере, на 7 лет позже дубликата ответа.
 – 
Maarten Bodewes
5 Май 2020 в 22:55
Мне, как новичку, это было проще всего реализовать. Спасибо!
 – 
frankfurt-laravel
9 Мар 2021 в 15:58

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

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

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

96
Ihor Patsian 23 Мар 2020 в 23:50

Класс 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).

76
Martijn Pieters 8 Фев 2019 в 17:14
Меня сбивает с толку, почему вы создаете индекс равным 0.
 – 
charles-allen
2 Авг 2017 в 16:53
Переменная index не повлияет на результат случайного числа. Вы можете инициализировать его любым удобным для вас способом, не беспокоясь об изменении результата. Надеюсь это поможет.
 – 
Matt R
2 Авг 2017 в 17:38
Точно... он совершенно не используется. Я бы инициализировал его непосредственно рандом: int index = rand.nextInt(i.Length);
 – 
charles-allen
2 Авг 2017 в 17:41
Или вообще нет. int index; \n index = rand... если вам нравятся объявления и присваивания в разных строках. Некоторые стандарты кодирования более строгие (и без видимой цели), чем другие.
 – 
Mark Storer
17 Сен 2019 в 21:24

Это можно сделать, просто выполнив оператор:

Randomizer.generate(0, 10); // Minimum of zero and maximum of ten

Ниже приведен его исходный код.

Файл Randomizer.java

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

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

58
Peter Mortensen 22 Апр 2022 в 17:01
6
Это могло быть редактирование другого примера, теперь это просто наглая копия для репутации. Указание на «ответ с наибольшим количеством голосов» тоже не очень прямое, оно может измениться.
 – 
Maarten Bodewes
20 Июн 2017 в 00:23
2
Это верно @MaartenBodewes. Когда я написал этот ответ, ответ с наибольшим количеством голосов выше все еще был написан как решение, подобное алгоритму. Теперь приведенное выше решение сильно изменилось, и теперь этот ответ выглядел как подражатель.
 – 
Abel Callejo
20 Июн 2017 в 03:36
2
Я действительно не понимаю, почему такие фундаментальные фрагменты кода не являются частью стандартных библиотек Java. Почему я должен это реализовать?
 – 
Leevi L
8 Окт 2019 в 11:31

Простите меня за придирчивость, но решение, предложенное большинством, т. е. 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 % или выше.

52
Azeem 23 Апр 2018 в 08:21
Почему бы не бросить исключение IllegalArgumentException, когда разница = Integer.MAX_VALUE? Тогда вам не нужен цикл while.
 – 
M.P. Korstanje
9 Янв 2015 в 13:27
3
Эта реализация предназначена для работы с любыми значениями min <= max, даже когда их разница равна или даже превышает MAX_VALUE. Запуск цикла до успешного завершения является распространенным шаблоном в этом случае, чтобы гарантировать равномерное распределение (если основной источник случайности является однородным). Random.nextInt(int) делает это внутри, когда аргумент не является степенью числа 2.
 – 
Christian Semrau
6 Май 2015 в 22:27

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

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

34
beat 16 Ноя 2016 в 15:08

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

 /**
   * @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;
 }

Вы можете привести его к целому числу, если хотите.

33
Simon 1 Авг 2019 в 09:25
Эта функция выдает одно и то же число снова и снова. В моем случае это было: 2147483647.
 – 
sokras
20 Июл 2017 в 10:38
Неудача: у вас есть функция, требующая двойника, а затем выполняющая +1? Это, безусловно, противоречит принципу наименьшего удивления. Что произойдет, если вы используете min = 0,1 и max = 0,2?
 – 
Maarten Bodewes
24 Апр 2018 в 00:26
Метод вызывает new Random (проверьте JavaDoc): «Создает новый генератор случайных чисел. Этот конструктор устанавливает начальное значение генератора случайных чисел в значение, которое, скорее всего, будет отличаться от любого другого вызова этого конструктора». Скорее всего, это может быть просто использование текущего времени в качестве начального значения. Если это время использует миллисекунды, то современные компьютеры достаточно быстры, чтобы генерировать такое же число. Но помимо этого 2147483647 равно Integer.MAX_VALUE; вывод, очевидно, зависит от ввода, который вы не указали.
 – 
Maarten Bodewes
24 Апр 2018 в 00:36
 rand.nextInt((max+1) - min) + min;
30
Youcef Laidani 20 Дек 2017 в 22:34

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

face = 1 + randomNumbers.nextInt(6);
19
GAMITG 21 Апр 2016 в 09:01

Вот полезный класс для генерации случайных 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
Garrett Hall 15 Фев 2012 в 20:19

Вы можете добиться этого в 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);
18
Martijn Pieters 8 Фев 2019 в 17: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);
    // ...
 }
17
Azeem 23 Апр 2018 в 08:22

Вот простой пример, который показывает, как сгенерировать случайное число из закрытого диапазона [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
Yakiv Mospan 28 Ноя 2014 в 03:58

Лучше использовать 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;
}
14
Peter Mortensen 6 Июл 2016 в 22:19
1
Это не так уж и хорошо, потому что, если он выполняется за ту же миллисекунду, вы получите тот же номер, вам нужно поместить инициализацию rand и setSeet вне метода.
 – 
maraca
16 Апр 2015 в 22:30
Вам нужно семя, да, но с использованием SecureRandom.
 – 
grep
17 Апр 2015 в 15:03
Извините, но тот, кто отклонил запрос на изменение, не имеет представления о программировании на Java. Это хорошее предложение, но оно ошибочно, потому что, если его выполнить за ту же миллисекунду, оно даст одинаковое число, а не случайное.
 – 
maraca
18 Апр 2015 в 12:19
Правильного решения нигде не найти, мало кто знает статические блоки инициализатора... это то, что вы должны использовать для установки начального числа: 1: private static int SecureRandom rand = new SecureRandom(); 2: static { 3: rand.setSeed(...); 4: }
 – 
maraca
18 Апр 2015 в 12:30
7
Нет абсолютно никакой необходимости раздавать SecureRandom, он будет раздаваться системой. Прямой вызов setSeed очень опасен, он может заменить (действительно случайное) начальное число датой. И это, безусловно, не приведет к SecureRandom, так как любой может угадать время и попытаться заполнить свой собственный экземпляр SecureRandom этой информацией.
 – 
Maarten Bodewes
2 Мар 2017 в 00:32
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);
}
16
Martijn Pieters 8 Фев 2019 в 17:15

В 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, который может стать источником путаницы и ошибок при неправильном использовании.

Однако, наоборот, нет способа явно установить начальное значение, поэтому может быть сложно воспроизвести результаты в ситуациях, когда это полезно, например, при тестировании или сохранении игровых состояний и т.п. В таких ситуациях можно использовать описанную ниже методику до версии 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 для выполнения этой задачи.

4230
MultiplyByZer0 14 Окт 2018 в 20:08
48
Для вызовов, где значение max равно Integer.MAX_VALUE, возможно переполнение, что приводит к java.lang.IllegalArgumentException. Вы можете попробовать с: randInt(0, Integer.MAX_VALUE). Кроме того, если nextInt((max-min) + 1) возвращает самое высокое значение (я полагаю, довольно редко), не будет ли оно снова переполняться (предположим, что min и max являются достаточно высокими значениями)? Как вести себя в подобных ситуациях?
 – 
Daniel
12 Авг 2014 в 14:34
Теперь доступен nextLong​(long origin, longbound). Размещение для ознакомления. Я не знаю, был ли он там, когда был отправлен ответ.
 – 
Jabir
5 Апр 2022 в 13:52

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

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

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

441
Martijn Pieters 8 Фев 2019 в 17:14

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

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);
27
Martijn Pieters 8 Фев 2019 в 17:15
Чем это отличается от предыдущих ответов?
 – 
Peter Mortensen
22 Апр 2022 в 17:04

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

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);
20
Martijn Pieters 8 Фев 2019 в 17:15
10
Я не вижу здесь ничего нового, что не было бы опубликовано в бесчисленных предыдущих постах.
 – 
Maarten Bodewes
20 Июн 2017 в 00:21
Эти бесчисленные сообщения трудно найти. Некоторые другие методы сверху
 – 
parsecer
26 Мар 2021 в 23:22
1
Да, размещение очередного дурака не поможет против этого. Проголосуйте за другие ответы или добавьте детали. В противном случае это просто репутационный фарм.
 – 
Maarten Bodewes
26 Мар 2021 в 23:31

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

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

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;
}
20
Peter Mortensen 22 Апр 2022 в 16:58
// Since the random number is between the min and max values, simply add 1. Почему? Мин не считается? Обычно диапазон составляет [min, max), где min включено, а max исключено. Неправильный ответ, проголосовал против.
 – 
Maarten Bodewes
2 Мар 2017 в 00:26
+1 добавляется, потому что getRandomNumberBetween генерирует случайное число без учета предоставленных конечных точек.
 – 
Luke Taylor
2 Мар 2017 в 12:53
2
Вероятность того, что число min + 1 будет в два раза больше, чем другое число, будет результатом getRandomNumberBetween!
 – 
Lii
17 Июн 2018 в 15:21

Обратите внимание, что этот подход более предвзят и менее эффективен, чем подход nextInt, https://stackoverflow.com/a/738651. /360211

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

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

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

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

Math.random() * ( Max - Min )

Это возвращает значение в диапазоне [0,Max-Min), где "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), а затем усечь десятичную часть, приведя к целому числу. Это достигается за счет:

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

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

5 + (int)(Math.random() * ((10 - 5) + 1))
1495
Martijn Pieters 8 Фев 2019 в 17:13
87
В документации Sun прямо говорится, что вам лучше использовать Random(), если вам нужен int вместо Math.random(), который создает двойное число.
 – 
Lilian A. Moraru
24 Фев 2012 в 03:26
7
Это на самом деле предвзято по сравнению с методами nextInt stackoverflow.com/a/738651/360211
 – 
weston
29 Дек 2016 в 16:35
8
«Смещенный» в этом случае означает, что после 2^53 выполнений некоторые числа будут иметь в среднем одно дополнительное появление.
 – 
Cephalopod
29 Авг 2019 в 12:48
Даже если я тоже использую это, я хочу отметить, что это не настоящее случайное число. Вот почему его не следует использовать для каких-либо функций безопасности. Но для любых случайных случаев это самый прямой метод.
 – 
Tobias
20 Окт 2020 в 16:28