FisherYates shuffle 基本思想 (Knuth shuffle):
Para mezclar una matriz a de n elementos (índices 0..n-1):
para i desde n − 1 hasta 1 hacer
j ← entero aleatorio con 0 ≤ j ≤ i
intercambiar a[j] y a[i]
JDK源代码如下:
/**
* Mueve cada elemento de la Lista a una nueva posición aleatoria en la lista
* usando el generador de números aleatorios especificado.
*
* @lista de parámetros
* la Lista para barajar
* @param aleatorio
* el generador de números aleatorios
*
* @throws Excepción de operación no admitida
* cuando no se admite reemplazar un elemento en la Lista
*/
@SuppressWarnings("sin marcar")
barajado vacío estático público (Lista <?> lista, Aleatorio aleatorio) {
if (!(listar instancia de RandomAccess)) {
Objeto[] matriz = list.toArray();
for (int i = matriz.longitud - 1; i > 0; i--) {
int índice = aleatorio.nextInt(i + 1);
si (índice < 0) {
índice = -índice;
}
Temperatura del objeto = matriz[i];
matriz[i] = matriz[índice];
matriz[índice] = temperatura;
}
int yo = 0;
ListIterator<Objeto> it = (ListIterator<Objeto>) lista
.listIterator();
mientras (it.hasNext()) {
it.siguiente();
it.set(array[i++]);
}
} demás {
Lista<Objeto> rawList = (Lista<Objeto>) lista;
for (int i = rawList.size() - 1; i > 0; i--) {
int índice = aleatorio.nextInt(i + 1);
si (índice < 0) {
índice = -índice;
}
rawList.set(índice, rawList.set(i, rawList.get(índice)));
}
}
}
público estático vacío principal (argumentos de cadena final []) {
Cambio de objetoTemp;
Lista<Integer> numList = new ArrayList<Integer>();
Lista<Integer> primeraLista = nueva ArrayList<Integer>();
Lista<Integer> secondList = new ArrayList<Integer>();
Lista<Integer> terceraLista = nueva ArrayList<Integer>();
Lista<Integer> cuartaLista = nueva ArrayList<Integer>();
para (int i = 1; i <= 100000; i++) {
numList.add(i);
primeraLista.add(i);
segundaLista.add(i);
terceraLista.add(i);
cuartaLista.add(i);
}
// primera reproducción aleatoria, use changeTemp
getHoraInicio();
int randInt = 0;
for (int i = 0, longitud = firstList.size(); i < longitud; i++) {
randInt = getRandom(i, primeraLista.tamaño());
cambiarTemp = primeraLista.get(i);
primeraList.set(i, primeraList.get(randInt));
firstList.set(randInt, javaShuffle.temp);
}
getEndTime("primer tiempo de ejecución aleatoria ");
// segunda mezcla, lista de intercambio
getHoraInicio();
for (int i = 0, longitud = secondList.size(); i < longitud; i++) {
randInt = getRandom(i, secondList.size());
secondList.set(i, secondList.set(randInt, secondList.get(i)));
}
getEndTime("segundo tiempo de ejecución aleatoria");
// tercera reproducción aleatoria, el cambio genera un int aleatorio
getHoraInicio();
Objeto[] tempArray = ThirdList.toArray();
Rand aleatorio = nuevo Aleatorio();
int j = 0;
for (int i = tempArray.length - 1; i > 0; i--) {
j = rand.nextInt(i + 1);
terceraList.set(i, terceraList.set(j, terceraList.get(i)));
}
getEndTime("tercer tiempo de ejecución aleatoria ");
// cuarta reproducción aleatoria, simula la reproducción aleatoria de Java
getHoraInicio();
Aleatorio aleatorio = nuevo Aleatorio();
if (!(cuarta instancia de Lista de Acceso Aleatorio)) {
Objeto[] matriz = cuartaLista.toArray();
for (int i = matriz.longitud - 1; i > 0; i--) {
int índice = aleatorio.nextInt(i + 1);
si (índice < 0) {
índice = -índice;
}
Temperatura del objeto = matriz[i];
matriz[i] = matriz[índice];
matriz[índice] = temperatura;
}
int yo = 0;
ListIterator<Integer> it = (ListIterator<Integer>) cuartaList.listIterator();
mientras (it.hasNext()) {
it.siguiente();
it.set((Entero) matriz[i++]);
}
} demás {
Lista<Integer> rawList = (Lista<Integer>) cuartaLista;
for (int i = rawList.size() - 1; i > 0; i--) {
int índice = aleatorio.nextInt(i + 1);
si (índice < 0) {
índice = -índice;
}
rawList.set(índice, rawList.set(i, rawList.get(índice)));
}
}
getEndTime("cuarto tiempo de ejecución aleatoria");
// java aleatoria
getHoraInicio();
Colecciones.shuffle(numList);
getEndTime("tiempo de ejecución aleatoria de Java ");
}
intercambio de vacío estático público (int a, int b) {
javaShuffle.temp = a;
a = b;
b = javaShuffle.temp;
}
public static int getRandom(final int bajo, final int alto) {
return (int) (Math.random() * (alto - bajo) + bajo);
}
público estático vacío getStartTime() {
javaShuffle.start = System.nanoTime();
}
getEndTime vacío estático público (cadena final s) {
javaShuffle.end = System.nanoTime();
System.out.println(s + ": " + (javaShuffle.end - javaShuffle.start) + "ns");
}
}
如果数值较小,例如100000级别,则输出大概是:
primer tiempo de ejecución aleatoria: 85029499ns
segundo tiempo de ejecución aleatoria: 80909474ns
tiempo de ejecución del tercer modo aleatorio: 71543926ns
cuarto tiempo de ejecución aleatoria: 76520595ns
tiempo de ejecución aleatoria de Java: 61027643ns
primer tiempo de ejecución aleatoria: 82326239ns
segundo tiempo de ejecución aleatoria: 78575611ns
tiempo de ejecución del tercer modo aleatorio: 95009632ns
cuarto tiempo de ejecución aleatoria: 105946897ns
tiempo de ejecución aleatoria de Java: 90849302ns
primer tiempo de ejecución aleatoria: 84539840ns
segundo tiempo de ejecución aleatoria: 85965575ns
tercer tiempo de ejecución aleatoria: 101814998ns
cuarto tiempo de ejecución aleatoria: 113309672ns
tiempo de ejecución aleatoria de Java: 35089693ns
primer tiempo de ejecución aleatoria: 87679863ns
segundo tiempo de ejecución aleatoria: 79991814ns
tercer tiempo de ejecución aleatoria: 73720515ns
cuarto tiempo de ejecución aleatoria: 78353061ns
tiempo de ejecución aleatoria de Java: 64146465ns
primer tiempo de ejecución aleatoria: 84314386ns
segundo tiempo de ejecución aleatoria: 80074803ns
tiempo de ejecución del tercer modo aleatorio: 74001283ns
cuarto tiempo de ejecución aleatoria: 79931321ns
tiempo de ejecución aleatoria de Java: 86427540ns
primer tiempo de ejecución aleatoria: 84315523ns
segundo tiempo de ejecución aleatoria: 81468386ns
tiempo de ejecución del tercer modo aleatorio: 75052284ns
cuarto tiempo de ejecución aleatoria: 79461407ns
tiempo de ejecución aleatoria de Java: 66607729ns
如果是10000000级别,大概如下:
primer tiempo de ejecución aleatoria: 2115703288ns
segundo tiempo de ejecución aleatoria: 3114045871ns
tercer tiempo de ejecución aleatoria: 4664426798ns
cuarto tiempo de ejecución aleatoria: 2962686695ns
tiempo de ejecución aleatoria de Java: 3246883026ns primer tiempo de ejecución aleatoria: 2165398466ns
segundo tiempo de ejecución aleatoria: 3129558913ns
tercer tiempo de ejecución aleatoria: 4147859664ns
cuarto tiempo de ejecución aleatoria: 2911849942ns
tiempo de ejecución aleatoria de Java: 4311703487ns primer tiempo de ejecución aleatoria: 2227462247ns
segundo tiempo de ejecución aleatoria: 3279548770ns
tercer tiempo de ejecución aleatoria: 4704344954ns
cuarto tiempo de ejecución aleatoria: 2942635980ns
tiempo de ejecución aleatoria de Java: 3933172427ns primer tiempo de ejecución aleatoria: 2200158789ns
segundo tiempo de ejecución aleatoria: 3172666791ns
tercer tiempo de ejecución aleatoria: 4715631517ns
cuarto tiempo de ejecución aleatoria: 2950817535ns
tiempo de ejecución aleatoria de Java: 3387417676ns primer tiempo de ejecución aleatoria: 2201124449ns
segundo tiempo de ejecución aleatoria: 3203823874ns
tercer tiempo de ejecución aleatoria: 4179926278ns
cuarto tiempo de ejecución aleatoria: 2913690411ns
tiempo de ejecución aleatoria de Java: 3571313813ns primer tiempo de ejecución aleatoria: 2163053190ns
segundo tiempo de ejecución aleatoria: 3073889926ns
tercer tiempo de ejecución aleatoria: 4493831518ns
cuarto tiempo de ejecución aleatoria: 2852713887ns
tiempo de ejecución aleatoria de Java: 3773602415ns
Java shuffle shuffle.
在进行大数据处理的时候,如果使用java库效率较低时,可以考虑使用其他方式.