Como eu gero números inteiros randoms dentro de um intervalo específico em Java?

Como faço para gerar um valor int random em um intervalo específico?

Eu tentei o seguinte, mas aqueles não funcionam:

Tentativa 1:

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

Tentativa 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`. 

    No Java 1.7 ou posterior , a maneira padrão de fazer isso é a seguinte:

     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); 

    Veja o JavaDoc relevante . Essa abordagem tem a vantagem de não precisar inicializar explicitamente uma instância java.util.Random , que pode ser uma fonte de confusão e erro se usada de forma inadequada.

    No entanto, inversamente, não há como definir explicitamente a semente, portanto, pode ser difícil reproduzir os resultados em situações em que isso é útil, como testar ou salvar estados de jogo ou semelhantes. Nessas situações, a técnica pré-Java 1.7 mostrada abaixo pode ser usada.

    Antes do Java 1.7 , a maneira padrão de fazer isso é a seguinte:

     import java.util.Random; /** * Returns a pseudo-random number between min and max, inclusive. * The difference between min and max can be at most * Integer.MAX_VALUE - 1. * * @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; } 

    Veja o JavaDoc relevante . Na prática, a class java.util.Random geralmente é preferível a java.lang.Math.random () .

    Em particular, não há necessidade de reinventar a roda de geração de inteiros randoms quando houver uma API direta dentro da biblioteca padrão para realizar a tarefa.

    Observe que essa abordagem é mais tendenciosa e menos eficiente do que uma abordagem nextInt , https://stackoverflow.com/a/738651/360211

    Um padrão padrão para realizar isso é:

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

    A function de biblioteca matemática Math.random () gera um valor duplo no intervalo [0,1) . Observe que esse intervalo não inclui o 1.

    Para obter um intervalo específico de valores primeiro, você precisa multiplicar pela magnitude do intervalo de valores que deseja cobrir.

     Math.random() * ( Max - Min ) 

    Isso retorna um valor no intervalo [0,Max-Min) , onde ‘Max-Min’ não está incluído.

    Por exemplo, se você quiser [5,10) , você precisa cobrir cinco valores inteiros para usar

     Math.random() * 5 

    Isso retornaria um valor no intervalo [0,5) , onde 5 não está incluído.

    Agora você precisa mudar esse intervalo para o intervalo que você está alvejando. Você faz isso adicionando o valor Min.

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

    Você agora receberá um valor no intervalo [Min,Max) . Seguindo nosso exemplo, isso significa [5,10) :

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

    Mas, isso ainda não inclui Max e você está obtendo um valor duplo. Para obter o valor Max incluído, você precisa adicionar 1 ao seu parâmetro de intervalo (Max - Min) e, em seguida, truncar a parte decimal enviando para um int. Isso é realizado via:

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

    E aí você tem isso. Um valor inteiro random no intervalo [Min,Max] ou pelo exemplo [5,10] :

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

    Usar:

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

    O inteiro x é agora o número random que tem um resultado possível de 5-10 .

    Usar:

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

    Com o java-8 eles introduziram o método ints(int randomNumberOrigin, int randomNumberBound) na class Random .

    Por exemplo, se você quiser gerar cinco inteiros randoms (ou um único) no intervalo [0, 10], faça:

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

    O primeiro parâmetro indica apenas o tamanho do IntStream gerado (que é o método sobrecarregado daquele que produz um IntStream ilimitado).

    Se você precisar fazer várias chamadas separadas, poderá criar um iterador primitivo infinito do stream:

     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(); } } 

    Você também pode fazer isso para valores double e long .

    Espero que ajude! 🙂

    Você pode editar seu segundo exemplo de código para:

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

    Apenas uma pequena modificação de sua primeira solução seria suficiente.

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

    Veja mais aqui para implementação do Random

    Equivalente ThreadLocalRandom da class java.util.Random para o ambiente multithread. Gerar um número random é realizado localmente em cada um dos segmentos. Então, temos um desempenho melhor, reduzindo os conflitos.

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

    x, y – intervalos, por exemplo, (1,10)

    A class Math.Random em Java é baseada em 0. Então, se você escrever algo assim:

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

    x estará entre 0-9 e 0-9 inclusive.

    Assim, dada a seguinte matriz de 25 itens, o código para gerar um número random entre 0 (a base da matriz) e array.length seria:

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

    Como i.length retornará 25 , o nextInt( i.length ) retornará um número entre o intervalo de 0-24 . A outra opção está indo com Math.Random que funciona da mesma maneira.

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

    Para um melhor entendimento, confira o post do fórum Random Intervals (archive.org) .

    Perdoe-me por ser meticuloso, mas a solução sugerida pela maioria, isto é, min + rng.nextInt(max - min + 1)) , parece perigosa devido ao fato de que:

    • rng.nextInt(n) não pode alcançar Integer.MAX_VALUE .
    • (max - min) pode causar estouro quando min é negativo.

    Uma solução infalível retornaria resultados corretos para qualquer min < = max dentro de [ Integer.MIN_VALUE , Integer.MAX_VALUE ]. Considere a seguinte implementação ingênua:

     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; } 

    Embora ineficiente, observe que a probabilidade de sucesso no loop while será sempre 50% ou mais.

    Gostaria de saber se algum dos methods de geração de números randoms fornecidos por uma biblioteca Apache Commons Math se encheckboxria na conta.

    Por exemplo: RandomDataGenerator.nextInt ou RandomDataGenerator.nextLong

    Vamos dar um exemplo.

    Suponha que eu queira gerar um número entre 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); 

    Vamos entender isso

    Inicialize max com o maior valor e min com o menor valor.

    Agora, precisamos determinar quantos valores possíveis podem ser obtidos. Para este exemplo, seria:

    5, 6, 7, 8, 9, 10

    Então, a contagem disso seria max – min + 1.

    ou seja, 10 – 5 + 1 = 6

    O número random irá gerar um número entre 0 e 5 .

    ou seja, 0, 1, 2, 3, 4, 5

    Adicionar o valor mínimo ao número random produziria:

    5, 6, 7, 8, 9, 10

    Por isso, obtemos o intervalo desejado.

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

    Gere um número random para a diferença de min e max usando o método nextint (n) e, em seguida, adicione o número min ao resultado:

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

    Aqui está uma class útil para gerar ints randoms em um intervalo com qualquer combinação de limites inclusivos / exclusivos:

     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; } } 

    No caso de lançar um dado, seria um número random entre 1 a 6 (não 0 a 6), portanto:

     face = 1 + randomNumbers.nextInt(6); 

    Esses methods podem ser convenientes para usar:

    Este método retornará um número random entre o valor min e max fornecido:

     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; } } 

    e este método retornará um número random do valor min e max fornecido (assim, o número gerado também pode ser o número mínimo ou máximo):

     public static int getRandomNumberFrom(int min, int max) { Random foo = new Random(); int randomNumber = foo.nextInt((max + 1) - min) + min; return randomNumber; } 
     int random = minimum + Double.valueOf(Math.random()*(maximum-minimun)).intValue(); 

    Ou dê uma olhada no RandomUtils do Apache Commons .

    Você pode conseguir isso de forma concisa no 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); 

    Quando você precisa de muitos números randoms, não recomendo a class Random na API. Tem apenas um período muito pequeno. Tente o twister Mersenne em vez disso. Existe uma implementação Java .

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

    Aqui está um exemplo simples que mostra como gerar um número random a partir do intervalo [min, max] fechado, enquanto min < = max is true

    Você pode reutilizá-lo como um campo na class de buraco, tendo também todos os methods Random.class em um só lugar.

    Exemplo de resultados:

     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 

    Fontes:

     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; } } 

    Apenas use a class Random :

     Random ran = new Random(); // Assumes max and min are non-negative. int randomInt = min + ran.nextInt(max - min + 1); 

    Eu encontrei este exemplo Gerar números randoms :


    Este exemplo gera números inteiros randoms em um intervalo específico.

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

    Um exemplo executado desta class:

     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. 

    Outra opção é apenas usar o 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); // ... } 

    A partir do Java 7, você não deve mais usar o Random . Para a maioria dos usos, o gerador de números randoms de escolha é agora ThreadLocalRandom .

    Para conjuntos de SplittableRandom garfo e streams paralelos, use SplittableRandom .

    Joshua Bloch. Java efetivo. Terceira edição.

    A partir do Java 8

    Para pools de junit de fork e streams paralelos, use SplittableRandom que geralmente é mais rápido, tem uma melhor independência estatística e propriedades de uniformidade em comparação com Random .

    Para gerar um int random no intervalo [0, 1_000]:

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

    Para gerar um array int[100] random de valores no intervalo [0, 1_000]:

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

    Para retornar um stream de valores randoms:

     IntStream stream = new SplittableRandom().ints(100, 0, 1_001); 

    Se você quiser tentar a resposta com o maior número de votos acima, você pode simplesmente usar este código:

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

    É apenas limpo e simples.

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

    OU

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

    É melhor usar SecureRandom ao invés de apenas 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.nextInt((max+1) - min) + min; 

    Isso está funcionando bem.