El problema planteado es el típico que sale habitualmente en foros de "escoger X números entre Y posibles de forma aleatoria y sin repeticiones". Una especie de Lotería Primitiva, vamos. Las soluciones habituales suelen tender a usar Random para generar números de forma aleatoria y comprobar si el número ya lo tenemos o no, solución que por probabilidad no podemos asegurar cuanto tiempo se tirará ejecutándose, o meter todos los números en una lista, escogerlos aleatoriamente e irlos borrando etc.
La segunda opción no es mala y al menos es "determinista*", pero si perdemos 5 minutos en el API de las colecciones, podemos llegar a esto (como extra devolvemos los números ordenados):
/**
* Devuelve numberCount números de entre 1 y
* maxNumber escogidos de forma aleatoria y
* ordenados.
*
* @param maxNumber
* @param numberCount
* @return La lista ordenada con los números seleccionados aleatoriamente.
*/
private static List selectRandomNumbers(int maxNumber, int numberCount)
{
List numberList = new LinkedList();
for (int i = 1; i <= maxNumber; i++)
{
numberList.add(i); //**
}
Collections.shuffle(numberList);
numberList =
numberList.subList(0, numberCount);
Collections.sort(numberList);
return numberList;
}
Y eso es todo. Dos métodos de Collections y uno de List hacen todo el trabajo y no tenemos que preocuparnos de nada. Los ingenieros del JDK se preocuparán de optimizar ese código y nosotros podemos dedicarnos al “core” de nuestro negocio.
La moraleja es... no hagas tú el trabajo si alguien ya lo ha hecho por ti. O como decía Mulder cuando programaba en Java... "La verdad, está en el API" ;P*: Determinista en cuanto sabemos el flujo de ejecución que va a seguir sin depender del azar.
**: Sí, estoy metiendo primitivas en una lista, cosa que solo funciona gracias al mágico autoboxing de las últimas versiones de Java y que no me gusta, pero para este caso el compilador escribiría el mismo código, así que...
Happy coding! EJ
No hay comentarios:
Publicar un comentario