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