Generando números aleatorios únicos en Java

Resuelto Ömer Faruk AK asked hace 13 años • 21 respuestas

Estoy intentando obtener números aleatorios entre 0 y 100. Pero quiero que sean únicos, no repetidos en una secuencia. Por ejemplo, si obtuve 5 números, deberían ser 82,12,53,64,32 y no 82,12,53,12,32. Usé esto, pero genera los mismos números en una secuencia.

Random rand = new Random();
selected = rand.nextInt(100);
Ömer Faruk AK avatar Nov 14 '11 06:11 Ömer Faruk AK
Aceptado
  • Agregue cada número en el rango secuencialmente en una estructura de lista .
  • Mézclalo .
  • Tome la primera 'n'.

Aquí hay una implementación simple. Esto imprimirá 3 números aleatorios únicos del rango del 1 al 10.

import java.util.ArrayList;
import java.util.Collections;

public class UniqueRandomNumbers {
    
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        for (int i=1; i<11; i++) list.add(i);
        Collections.shuffle(list);
        for (int i=0; i<3; i++) System.out.println(list.get(i));
    }
}

La primera parte de la solución con el enfoque original, como señaló Mark Byers en una respuesta ahora eliminada, es usar solo una Randominstancia.

Eso es lo que hace que los números sean idénticos. Una Randominstancia se inicializa según la hora actual en milisegundos. Para un valor inicial particular, la instancia 'aleatoria' devolverá exactamente la misma secuencia de números pseudoaleatorios .

Andrew Thompson avatar Nov 13 '2011 23:11 Andrew Thompson

Con Java 8+, puede utilizar el intsmétodo para Randomobtener IntStreamvalores aleatorios distincty luego limitreducir la secuencia a una cantidad de valores aleatorios únicos.

ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);

Randomtambién tiene métodos que crean LongStreams y DoubleStreams si los necesita.

Si desea que todos (o una gran cantidad) de los números en un rango estén en orden aleatorio, podría ser más eficiente agregar todos los números a una lista, mezclarlos y tomar la primera n porque el ejemplo anterior está implementado actualmente. generando números aleatorios en el rango solicitado y pasándolos a través de un conjunto (de manera similar a la respuesta de Rob Kielty ), lo que puede requerir generar muchos más que la cantidad pasada para limitar porque la probabilidad de generar un nuevo número único disminuye con cada uno encontrado. Aquí hay un ejemplo de la otra manera:

List<Integer> range = IntStream.range(0, 100).boxed()
        .collect(Collectors.toCollection(ArrayList::new));
Collections.shuffle(range);
range.subList(0, 99).forEach(System.out::println);
Alex - GlassEditor.com avatar Jul 27 '2015 15:07 Alex - GlassEditor.com
  1. Crea una matriz de 100 números y luego aleatoriza su orden.
  2. Diseñe un generador de números pseudoaleatorios que tenga un rango de 100.
  3. Cree una matriz booleana de 100 elementos, luego establezca un elemento como verdadero cuando elija ese número. Cuando elija el siguiente número, verifique la matriz y vuelva a intentarlo si el elemento de la matriz está configurado. (Puede crear una matriz booleana fácil de borrar con una matriz longdonde cambia y enmascara para acceder a bits individuales).
Hot Licks avatar Nov 13 '2011 23:11 Hot Licks