Как мне сгенерировать случайное значение int в определенном диапазоне?
Я пробовал следующее, но они не работают:
Попытка 1:
randomNum = minimum + (int)(Math.random() * maximum);
Ошибка: randomNum может быть больше, чем maximum.
Попытка 2:
Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum = minimum + i;
Ошибка: randomNum может быть меньше minimum.
Когда вам нужно много случайных чисел, я не рекомендую использовать класс Random в API. Просто у него слишком маленький период. Вместо этого попробуйте Твистер Мерсенна. Есть реализация Java.
randomNum = minimum + (int)(Math.random() * (maximum - minimum);



Использовать:
minimum + rn.nextInt(maxValue - minvalue + 1)
В 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-интерфейс для выполнения этой задачи.
Для вызовов, для которых значение max равно Integer.MAX_VALUE, возможно переполнение, что приведет к возникновению java.lang.IllegalArgumentException. Вы можете попробовать: randInt(0, Integer.MAX_VALUE). Кроме того, если nextInt((max-min) + 1) возвращает самое высокое значение (я полагаю, довольно редко), не переполнится ли он снова (предположим, что min и max - достаточно высокие значения)? Как справляться с подобными ситуациями?
@momo класс RANDOM поддерживает nextLong. Вы можете использовать это вместо nextInt в течение долгого времени.
@MoisheLipsker Должно быть, nextLong не принимает привязку как nextInteger
@momo Обратитесь за помощью к double. Просто так: long val = ((long) (r.nextDouble() * (max - min))) + min
Да, я уже делаю это, используя Math.random (), который делает это: public static long random (long min, long max) {return min + Math.round (Math.random () * ((max - min)) ); }
Этот фрагмент (который, вероятно, копируют тысячи людей) ПЛОХОЙ. Он производит мусор. Просто ThreadLocalRandom.current().nextInt(min, max).
@leventov ThreadLocalRandom был добавлен в Java спустя два с половиной года после того, как этот вопрос был впервые задан. Я всегда твердо придерживался мнения, что управление экземпляром Random выходит за рамки вопроса.
@AbhishekSingh Комментарии пытаются решить эту проблему, но более подробно: nextInt (N) возвращает число от 0 до N - 1, то есть никогда не вернет N в результате. В этом случае мы хотим включить N в наш возможный диапазон значений, поэтому мы добавляем единицу: nextInt (N + 1) => возвращает число в диапазоне от 0 до N, включая как 0, так и N.
В Android Random rand = new Random ();
@Webserveis Это рассматривается в комментариях к примеру. Краткая версия - вы не должны = new Random () для каждого вызова функции, иначе ваши результаты не будут достаточно случайными для многих случаев.
Разве вы не должны инициализировать rand = new Random ()?
@ChitKhine Не при каждом вызове функции. Алгоритм RNG под капотом Random работает хорошо (достаточно для некриптографических приложений) при генерации последовательных случайных чисел. Однако, если экземпляр Random воссоздается при каждом вызове, это означает, что вместо правильного RNG вы будете получать «случайные» числа на основе того, какое начальное число выбирается каждый раз - часто это основано на системных часах. Это может дать явно неслучайные результаты. Вместо этого вам следует рассмотреть возможность создания экземпляра Random вне области действия метода. Пример кода пытается решить эту проблему.
Используйте ThreadLocalRandom.current().nextBytes(chunk);, если хотите спасти себя от new Random(). Спасибо действительно популярный вопрос за генерацию случайных целых чисел в Java.
и если вы используете для Android java ThreadLocalRandom.current (). nextInt (1, 100), для этого требуется минимальный уровень API 21
rand.nextInt((max+1) - min) + min;
Интересно, подойдет ли какой-либо из методов генерации случайных чисел, предоставляемых библиотекой Математика Apache Commons, счету.
Например: RandomDataGenerator.nextInt или RandomDataGenerator.nextLong.
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();
Или взгляните на RandomUtils от Apache Commons.
Это полезно, но будьте осторожны с небольшим недостатком: сигнатуры методов похожи на: nextDouble (double startInclusive, double endInclusive), но если вы посмотрите внутрь методов, endInclusive на самом деле должен быть endExclusive.
Double.valueOf(Math.random()*(maximum-minimun)).intValue() - довольно запутанный (и неэффективный) способ сказать (int)(Math.random()*(maximum-minimun))…
Несоответствие орфографии для минимального возвращаемого минимума + Double.valueOf (Math.random () * (максимум - минимум)). IntValue ();
Вы можете отредактировать второй пример кода, чтобы:
Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum = rn.nextInt(range) + minimum;
Обратите внимание, что этот подход более пристрастен и менее эффективен, чем подход nextInt, https://stackoverflow.com/a/738651/360211
Один из стандартных шаблонов для этого:
Min + (int)(Math.random() * ((Max - Min) + 1))
Функция библиотеки Ява 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))
В документации Sun прямо говорится, что вам лучше использовать Random (), если вам нужен int вместо Math.random (), который производит double.
Это на самом деле предвзято по сравнению с методами nextInt stackoverflow.com/a/738651/360211
"Смещенный" в этом случае означает, что после 2 ^ 53 казней у некоторых номеров в среднем будет одно дополнительное появление.
Даже подумав, что я тоже использую это, я хочу указать, что это не настоящее случайное число. Вот почему его не следует использовать для каких-либо функций безопасности. Но для любых случайных случаев это самый простой способ.
Класс Math.Random в Ява основан на 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).
+1 для ссылки на скриншот архива wayBackMachine, и ваш ответ по-прежнему полезен, чтобы получить "случайные" целые числа в определенном диапазоне.
Меня сбивает с толку, почему вы создаете экземпляр index равным 0.
@CodeConfident Переменная index не влияет на результат случайного числа. Вы можете инициализировать его любым способом, не беспокоясь об изменении результата. Надеюсь это поможет.
Точно ... он совершенно не используется. Я бы инициализировал его прямо рандом: int index = rand.nextInt(i.Length);
Или совсем нет. int index; \n index = rand..., если вы увлекаетесь объявлениями и присваиваниями по разным линиям. Некоторые стандарты кодирования более строгие (и без видимой цели), чем другие.
Использовать:
Random ran = new Random();
int x = ran.nextInt(6) + 5;
Целое число x теперь является случайным числом, имеющим возможный результат 5-10.
В случае броска кубика это будет случайное число от 1 до 6 (а не от 0 до 6), поэтому:
face = 1 + randomNumbers.nextInt(6);
rand.nextInt((max+1) - min) + min;
Это нормально работает.
Простите меня за разборчивость, но решение, предложенное большинством, то есть 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% или выше.
Почему бы не создать исключение IllegalArgumentException, если разница = Integer.MAX_VALUE? Тогда вам не нужен цикл while.
@mpkorstanje Эта реализация предназначена для работы с любыми значениями min <= max, даже если их разница равна или даже больше MAX_VALUE. Запуск цикла до успеха является в этом случае обычным шаблоном, чтобы гарантировать равномерное распределение (если основной источник случайности однороден). Random.nextInt (int) делает это внутренне, когда аргумент не является степенью двойки.
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);
}
Другой вариант - просто использовать 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);
// ...
}
Вот полезный класс для генерации случайного 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;
}
}
Я нашел этот пример Сгенерировать случайные числа:
В этом примере генерируются случайные целые числа в определенном диапазоне.
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.
Эти методы могут быть удобны в использовании:
Этот метод вернет случайное число между, указанное минимальное и максимальное значение:
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;
}
// Since the random number is between the min and max values, simply add 1. Почему? Минут не в счет? Обычно диапазон составляет [min, max), где min включено, а max исключено. Неверный ответ, проголосовали против.
@MaartenBodewes +1 добавлен, потому что getRandomNumberBetween генерирует случайное число, исключая предоставленные конечные точки.
Число min + 1 в два раза чаще, чем другое число, будет результатом getRandomNumberBetween!
Вы можете использовать этот фрагмент кода, который решит вашу проблему:
Random r = new Random();
int myRandomNumber = 0;
myRandomNumber = r.nextInt(maxValue-minValue+1)+minValue;
Используйте myRandomNumber (который даст вам число в пределах диапазона).
Я просто генерирую случайное число с помощью Math.random () и умножаю его на большое число, скажем, 10000. Итак, я получаю число от 0 до 10 000 и называю его i. Теперь, если мне нужны числа между (x, y), сделайте следующее:
i = x + (i % (y - x));
Итак, все i - это числа от x до y.
Чтобы устранить смещение, указанное в комментариях, вместо того, чтобы умножать его на 10000 (или большое число), умножьте его на (y-x).
Один из моих друзей задал мне сегодня тот же вопрос в университете (его требования заключались в том, чтобы сгенерировать случайное число от 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));
Попробуйте использовать другие диапазоны, ваш код не дает единообразных значений в данном диапазоне. numberOne = 3.5 и numberTwo = 7.2 дает значения только в диапазоне 4,73–5,96.
ThreadLocalRandom эквивалент класса java.util.Random для многопоточной среды. Генерация случайного числа выполняется локально в каждом из потоков. Так что у нас есть лучшая производительность за счет уменьшения конфликтов.
int rand = ThreadLocalRandom.current().nextInt(x,y);
x, y - интервалы, например. (1,10)
Попробуйте использовать класс 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;
}
}
Это можно сделать, просто выполнив инструкцию:
Randomizer.generate(0,10); //min of zero, max of ten
Ниже его исходный код
public class Randomizer {
public static int generate(int min,int max) {
return min + (int)(Math.random() * ((max - min) + 1));
}
}
Это просто и понятно.
Это могло быть правка другого примера, теперь это просто явная копия для репутации. Указать «ответ с наибольшим количеством голосов» тоже не очень прямо, это может измениться.
Правильно @MaartenBodewes. Когда я писал этот ответ, ответ с наибольшим количеством голосов выше все еще был написан как решение, подобное алгоритму. Вышеупомянутое решение сильно изменилось, и теперь этот ответ выглядел как подражатель.
Я действительно не понимаю, почему такие фундаментальные фрагменты кода не являются частью стандартных библиотек Java. Почему я должен это реализовать?
Думаю, этот код сработает. Пожалуйста, попробуйте это:
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);
}
}
Я думаю линейно нормализовать сгенерированные случайные числа в желаемый диапазон, используя следующее. Пусть 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);
}
Просто используйте класс Случайный:
Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);
Я не вижу здесь ничего нового, что не было опубликовано в бесчисленных предыдущих постах.
@MaartenBodewes Эти бесчисленные сообщения трудно найти. Некоторые другие методы наверху
Да, публикация очередного обмана не поможет против этого. Проголосуйте за другие ответы или добавьте детали. В противном случае это просто фарм репутации.
Я просто укажу, что не так с решениями, предоставленными в вопросе, и почему ошибки.
Решение 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;
Также вернет желаемый результат.
% имеет еще большую проблему смещения распределения. Недавно я написал об этом в блоге: jaroslawpawlak.wordpress.com/2014/10/11/…
Вы можете использовать класс 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;
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;
}
}
Возьмем пример.
Предположим, я хочу сгенерировать число между 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);
Давайте разберемся в этом ...
Initialize max with highest value and min with the lowest value.
Now, we need to determine how many possible values can be obtained. For this example, it would be:
5, 6, 7, 8, 9, 10
So, count of this would be max - min + 1.
i.e. 10 - 5 + 1 = 6
The random number will generate a number between 0-5.
i.e. 0, 1, 2, 3, 4, 5
Adding the min value to the random number would produce:
5, 6, 7, 8, 9, 10
Hence we obtain the desired range.
С помощью java-8 они представили метод 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. Я надеюсь, что это помогает! :)
Я бы посоветовал вам создать экземпляр randomIterator только один раз. См. Комментарий Грега Кейса к его собственному ответу.
Вот простой пример, который показывает, как сгенерировать случайное число из закрытого диапазона [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;
}
}
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;
}
Если max и min большие, это вызовет проблемы с переполнением и даст неверные результаты.
Достаточно небольшой модификации вашего первого решения.
Random rand = new Random();
randomNum = minimum + rand.nextInt((maximum - minimum) + 1);
Подробнее о реализации Random см. Здесь
Для минимума <= значение <максимум я сделал то же самое с Math: randomNum = минимум + (целое число) (Math.random () * (максимум-минимум));, но на приведение типов не очень приятно смотреть;)
Двойной ответ с опозданием минимум на 7 лет.
Для меня как новичка это было наиболее легко реализовать. Спасибо!
Лучше использовать 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;
}
Это не так хорошо, потому что, если он выполняется за одну и ту же секунду, вы получите то же число, вам нужно поместить инициализацию rand и setSeet вне метода.
Да, вам нужен seed, но с использованием SecureRandom.
Извините, но тот, кто отклонил запрос на изменение, понятия не имеет о программировании на Java Это хорошее предложение, но как бы то ни было, оно неверное., потому что, если он выполняется за ту же миллисекунду, он даст то же число, а не случайное.
Правильного решения нигде не найти, не многие люди знают блоки статического инициализатора ... это то, что вы должны использовать для установки семени: 1: private static int SecureRandom rand = new SecureRandom(); 2: static { 3: rand.setSeed(...); 4: }
в моем примере нужно удалить int в строке one. И две первые строки внутри вашей функции. Остальное остается прежним.
Засев SecureRandom не требуется, он будет засеян системой. Прямой вызов setSeed очень опасен, он может заменить (действительно случайное) начальное число датой. И это, безусловно, приведет к нет в SecureRandom, так как любой может угадать время и попытаться заполнить свой собственный экземпляр SecureRandom этой информацией.
Вы можете сделать что-то вроде этого:
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));
}
}
Сгенерируйте случайное число для разницы min и max с помощью метода nextint (п), а затем добавьте минимальное число к результату:
Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);
Случайное число из диапазона [min..max] включительно:
int randomFromMinToMaxInclusive = ThreadLocalRandom.current()
.nextInt(min, max + 1);
Это сгенерирует Список случайных чисел с диапазон (мин. - макс.) с нет дубликата.
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);
}
}
Надеюсь, что это поможет вам.
Это становится сложным, если вы нашли большинство чисел в пределах диапазона; есть более эффективные способы сделать это (например, генерировать случайное число с максимальным значением, равным количеству оставшихся элементов, и пропускать уже найденные числа. На самом деле, как в Бинго.
Большинство из приведенных выше предложений не рассматривают «переполнение», например: min = Integer.MIN_VALUE, max = 100. Один из правильных подходов, которые у меня есть до сих пор:
final long mod = max- min + 1L;
final int next = (int) (Math.abs(rand.nextLong() % mod) + min);
Создание операторов защиты (если значение> другое значение, тогда исключение) также должно работать (при условии, что диапазон не установлен пользователем / системой).
Вы могли бы использовать
RandomStringUtils.randomNumeric(int count)
метод также из общего доступа Apache.
Другой подход с использованием 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)
}
Хороший. Вы можете использовать List<Integer> ls = range.boxed().collect(Collectors.toList());
new Integer (i) также был избыточным, но он все равно удаляется кодом из моего предыдущего комментария.
Разве это не дает 6 чисел в случайном порядке, а не одно число? Кажется немного расточительным. И если мне нужно еще одно случайное число, я не могу просто взять второе в списке, потому что у него нет шансов быть таким же, как уже взятое число.
Я создал метод получения уникального целого числа в заданном диапазоне.
/*
* 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;
}
Используя Java 8 Streams,
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.
Если вы уже используете Commons Lang API 2.x или последнюю версию, то есть один класс для генерации случайных чисел RandomUtils.
public static int nextInt(int n)
Возвращает псевдослучайное, равномерно распределенное значение int от 0 (включительно) до указанного значения (исключая) из последовательности Math.random ().
Параметры:
int random = RandomUtils.nextInt(1000000);
Примечание: в RandomUtils есть много методов генерации случайных чисел
Я использую это:
/**
* @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;
}
Вы можете преобразовать его в целое число, если хотите.
Эта функция выдает одно и то же число снова и снова. В моем случае это было: 2147483647
Ошибка: у вас есть функция, которая требует двойного, а затем выполняет +1? Это определенно противоречит принципу наименьшего удивления. Что произойдет, если вы используете min = 0,1 и max = 0,2?
@sokras метод вызывает new Random (проверьте JavaDoc): «Создает новый генератор случайных чисел. Этот конструктор устанавливает для начального числа генератора случайных чисел значение, которое, скорее всего, будет отличаться от любого другого вызова этого конструктора». Скорее всего, можно просто использовать текущее время в качестве начального числа. Если в это время используются миллисекунды, то современные компьютеры достаточно быстры, чтобы сгенерировать то же число. Но помимо этого 2147483647 - это Integer.MAX_VALUE; вывод, очевидно, зависит от ввода, который вы не указали.
Вы можете вкратце добиться этого в 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);
Это самый простой способ сделать это.
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.
Простой способ сгенерировать 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.
Помимо того, что есть другие ответы, в которых используются потоки, по крайней мере, они не создают новый поток в цикле, теперь это действительно не имеет смысла.
Random random = new Random();
int max = 10;
int min = 3;
int randomNum = random.nextInt(max) % (max - min + 1) + min;
Объяснение было бы в порядке.
Чтобы сгенерировать случайное число «между двумя числами», используйте следующий код:
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.
В https://sourceforge.net/projects/stochunit/ есть библиотека для обработки выбора диапазонов.
StochIntegerSelector randomIntegerSelector = new StochIntegerSelector();
randomIntegerSelector.setMin(-1);
randomIntegerSelector.setMax(1);
Integer selectInteger = randomIntegerSelector.selectInteger();
Имеет краевое включение / преклюзию.
Приведенный ниже код генерирует случайное число от 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);
Допустим, вам нужен диапазон от 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);
}
Это не выглядит правильным. В "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;»
As of Java 7, you should no longer use
Random. For most uses, the random number generator of choice is nowThreadLocalRandom.
For fork join pools and parallel streams, useSplittableRandom.
Джошуа Блох. Эффективная Java. Третье издание.
Для пулов fork join и параллельных потоков используйте 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);
Есть ли причина, по которой пример включает .parallel()? Мне кажется, что создание 100 случайных чисел было бы слишком тривиально, чтобы гарантировать параллелизм.
@Johnbot Спасибо за комментарий, вы правы. Но основная причина заключалась в том, чтобы показать API (конечно, умный путь - измерить производительность перед использованием обработки parallel). Кстати, для массива элементов 1_000_000 версия parallel на моей машине была в 2 раза быстрее по сравнению с последовательной.
Ниже приведен еще один пример использования 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);
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));
}
}
Вы также можете использовать
import java.util.concurrent.ThreadLocalRandom;
Random random = ThreadLocalRandom.current();
Однако этот класс плохо работает в многопоточной среде.
Объяснение было бы в порядке.
Внесение следующего изменения в Попытка 1 должно работать -
randomNum = minimum + (int)(Math.random() * (maximum - minimum) );
Проверьте рабочий код это.
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);
}
Для общего использования используйте java.util for Random.
Вы можете определить свой минимальный и максимальный диапазон, чтобы получить эти результаты.
Random rand=new Random();
rand.nextInt((max+1) - min) + min;
Вы можете сделать как показано ниже.
import java.util.Random;
public class RandomTestClass {
public static void main(String[] args) {
Random r = new Random();
int max, min;
Scanner scanner = new Scanner(System.in);
System.out.println("Enter maximum value : ");
max = scanner.nextInt();
System.out.println("Enter minimum value : ");
min = scanner.nextInt();
int randomNum;
randomNum = r.nextInt(max) + min;
System.out.println("Random Number : " + randomNum);
}
}
Можно использовать следующий код:
ThreadLocalRandom.current().nextInt(rangeStart, rangeEndExclusive)
Было несколько ответов, которые уже предлагали ThreadLocalRandom. Если вопрос был защищен, пожалуйста, будьте особенно осторожны, чтобы не дублировать ответы.
вот функция, которая возвращает ровно одно целое случайное число в диапазоне, определяемомlowerBoundIncludedа такжеupperBoundIncluded, по просьбе пользователь 42155
SplittableRandom splittableRandom = new SplittableRandom();
BiFunction<Integer,Integer,Integer> randomInt = (lowerBoundIncluded, upperBoundIncluded)
-> splittableRandom.nextInt( lowerBoundIncluded, upperBoundIncluded + 1 );
randomInt.apply( …, … ); // gets the random number
… Или короче для одноразовой генерации случайного числа
new SplittableRandom().nextInt( lowerBoundIncluded, upperBoundIncluded + 1 );
Следующий фрагмент даст случайное значение от 0 до 10000:
import java.util.Random;
public class Main
{
public static void main(String[] args) {
Random rand = new Random();
System.out.printf("%04d%n", rand.nextInt(10000));
}
}
Спасибо за этот фрагмент кода, который может предоставить некоторую краткосрочную помощь. Правильное объяснение значительно улучшит его долгосрочной ценности, показывая Зачем, что это хорошее решение проблемы, и сделало бы его более полезным для будущих читателей с другими подобными вопросами. Пожалуйста, редактировать свой ответ, чтобы добавить некоторые пояснения, включая сделанные вами предположения. В частности, не очевидно, как этот код принимает нижнюю и верхнюю границы постановки задачи.
int func(int max, int min){
int range = max - min + 1;
// Math.random() function will return a random no between [0.0,1.0).
int res = (int) ( Math.random()*range)+min;
return res;
}
Похоже, это просто повторение многих из существующих ответов.
Используйте Apache Lang3 Commons
Integer.parseInt(RandomStringUtils.randomNumeric(6, 6));
Минимальное значение от 100000 до максимального значения 999999
Зачем усложнять жизнь, когда можно найти простые решения :)
Я подумал, что это было проще всего с учетом случайных чисел в диапазоне.
Сгенерированный номер может начинаться с нуля!
Это дает строку, а не целое число, и поэтому не является ответом на вопрос.
Возвращает \ p {Digit}
Вы можете использовать следующий способ сделать это
int range = 10;
int min = 5
Random r = new Random();
int = r.nextInt(range) + min;
Чтобы избежать повторения того, что было сказано несколько раз, я показываю альтернативу для тех, кому нужен криптографически более сильный генератор псевдослучайных чисел с использованием класса SecureRandom, который расширяет класс Random. Из источник можно прочитать:
This class provides a cryptographically strong random number generator (RNG). A cryptographically strong random number minimally complies with the statistical random number generator tests specified in FIPS 140-2, Security Requirements for Cryptographic Modules, section 4.9.1. Additionally, SecureRandom must produce non-deterministic output. Therefore any seed material passed to a SecureRandom object must be unpredictable, and all SecureRandom output sequences must be cryptographically strong, as described in RFC 1750: Randomness Recommendations for Security.
A caller obtains a SecureRandom instance via the no-argument constructor or one of the getInstance methods:
SecureRandom random = new SecureRandom();Many SecureRandom implementations are in the form of a pseudo-random number generator (PRNG), which means they use a deterministic algorithm to produce a pseudo-random sequence from a true random seed. Other implementations may produce true random numbers, and yet others may use a combination of both techniques.
Чтобы сгенерировать случайное число между значениями min и max включительно:
public static int generate(SecureRandom secureRandom, int min, int max) {
return min + secureRandom.nextInt((max - min) + 1);
}
для заданных значений min (включительно) и max (исключая):
return min + secureRandom.nextInt((max - min));
Пример работающего кода:
public class Main {
public static int generate(SecureRandom secureRandom, int min, int max) {
return min + secureRandom.nextInt((max - min) + 1);
}
public static void main(String[] arg) {
SecureRandom random = new SecureRandom();
System.out.println(generate(random, 0, 2 ));
}
}
Такие источники, как переполнение стека, baeldung, выродки, обеспечивают сравнения между классами Random и SecureRandom.
Из baeldung можно прочитать:
The most common way of using SecureRandom is to generate int, long, float, double or boolean values:
int randomInt = secureRandom.nextInt();
long randomLong = secureRandom.nextLong();
float randomFloat = secureRandom.nextFloat();
double randomDouble = secureRandom.nextDouble();
boolean randomBoolean = secureRandom.nextBoolean();For generating int values we can pass an upper bound as a parameter:
int randomInt = secureRandom.nextInt(upperBound);
In addition, we can generate a stream of values for int, double and long:
IntStream randomIntStream = secureRandom.ints();
LongStream randomLongStream = secureRandom.longs();
DoubleStream randomDoubleStream = secureRandom.doubles();For all streams we can explicitly set the stream size:
IntStream intStream = secureRandom.ints(streamSize);
Этот класс предлагает несколько других вариантов (например., выбирает базовый генератор случайных чисел), которые выходят за рамки этого вопроса.
Прежде чем опубликовать новый ответ, подумайте, что на этот вопрос уже есть более 65 ответов. Пожалуйста, убедитесь, что ваш ответ содержит информацию, которой нет среди существующих ответов.