shuffle(List<?> list, Random rnd)
/**
* Randomly permute the specified list using the specified source of
* randomness. All permutations occur with equal likelihood
* assuming that the source of randomness is fair.<p>
*
* This implementation traverses the list backwards, from the last element
* up to the second, repeatedly swapping a randomly selected element into
* the "current position". Elements are randomly selected from the
* portion of the list that runs from the first element to the current
* position, inclusive.<p>
*
* This method runs in linear time. If the specified list does not
* implement the {@link RandomAccess} interface and is large, this
* implementation dumps the specified list into an array before shuffling
* it, and dumps the shuffled array back into the list. This avoids the
* quadratic behavior that would result from shuffling a "sequential
* access" list in place.
*
* @param list the list to be shuffled.
* @param rnd the source of randomness to use to shuffle the list.
* @throws UnsupportedOperationException if the specified list or its
* list-iterator does not support the <tt>set</tt> operation.
*/
public static void shuffle(List<?> list, Random rnd) {
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
for (int i=size; i>1; i--)
swap(list, i-1, rnd.nextInt(i));
} else {
Object[] arr = list.toArray();
// Shuffle array
for (int i=size; i>1; i--)
swap(arr, i-1, rnd.nextInt(i));
// Dump array back into list
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
ListIterator it = list.listIterator();
for (int i=0; i<arr.length; i++) {
it.next();
it.set(arr[i]);
}
}
}
使用指定的随机源随机排列指定的列表。假设随机性来源是公平的,所有排列都以相同的可能性发生。
此实现向后遍历列表,从最后一个元素到第二个元素,反复将随机选择的元素交换到“当前位置”。元素是从列表中从第一个元素到当前位置(含)的部分中随机选择的。
该方法以线性时间运行。如果指定的列表未实现 {@link RandomAccess} 接口并且很大,则此实现会在打乱指定列表之前将其转储到数组中,并将打乱后的数组转储回列表中。这避免了因对“顺序访问”列表进行改组而导致的二次行为。
@param list 要洗牌的列表。
@param rnd 用于洗牌列表的随机性来源。
如果指定的列表或其列表迭代器不支持 set
操作,则抛出 UnsupportedOperationException。
shuffle(List<?> list)
/**
* Randomly permutes the specified list using a default source of
* randomness. All permutations occur with approximately equal
* likelihood.
*
* <p>The hedge "approximately" is used in the foregoing description because
* default source of randomness is only approximately an unbiased source
* of independently chosen bits. If it were a perfect source of randomly
* chosen bits, then the algorithm would choose permutations with perfect
* uniformity.
*
* <p>This implementation traverses the list backwards, from the last
* element up to the second, repeatedly swapping a randomly selected element
* into the "current position". Elements are randomly selected from the
* portion of the list that runs from the first element to the current
* position, inclusive.
*
* <p>This method runs in linear time. If the specified list does not
* implement the {@link RandomAccess} interface and is large, this
* implementation dumps the specified list into an array before shuffling
* it, and dumps the shuffled array back into the list. This avoids the
* quadratic behavior that would result from shuffling a "sequential
* access" list in place.
*
* @param list the list to be shuffled.
* @throws UnsupportedOperationException if the specified list or
* its list-iterator does not support the <tt>set</tt> operation.
*/
public static void shuffle(List<?> list) {
Random rnd = r;
if (rnd == null)
r = rnd = new Random(); // harmless race.
shuffle(list, rnd);
}
使用默认的随机源随机排列指定的列表。所有排列发生的可能性大致相等。
在前面的描述中使用对冲“大约”是因为默认的随机性源仅大约是独立选择的位的无偏源。如果它是随机选择位的完美来源,那么算法将选择具有完美均匀性的排列。
此实现向后遍历列表,从最后一个元素到第二个元素,反复将随机选择的元素交换到“当前位置”。元素是从列表中从第一个元素到当前位置(含)的部分中随机选择的。
该方法以线性时间运行。如果指定的列表未实现 {@link RandomAccess} 接口并且很大,则此实现会在打乱指定列表之前将其转储到数组中,并将打乱后的数组转储回列表中。这避免了因对“顺序访问”列表进行改组而导致的二次行为。
@param list 要洗牌的列表。
如果指定的列表或其列表迭代器不支持 set
操作,则抛出 UnsupportedOperationException。
使用示例
- 示例代码
public static void main(String[] args){
Random rand=new Random(47);
Integer[] ia={0,1,2,3,4,5,6,7,8,9};
List<Integer> list=new ArrayList<Integer>(Arrays.asList(ia));
System.out.println("Before shufflig: "+list);
Collections.shuffle(list,rand);
System.out.println("After shuffling: "+list);
System.out.println("array: "+Arrays.toString(ia));
List<Integer> list1=Arrays.asList(ia);
System.out.println("Before shuffling: "+list1);
Collections.shuffle(list1,rand);
System.out.println("After shuffling: "+list1);
System.out.println("array: "+Arrays.toString(ia));
}
- 运行结果
Before shufflig: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
After shuffling: [3, 5, 2, 0, 7, 6, 1, 4, 9, 8]
array: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Before shuffling: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
After shuffling: [8, 0, 5, 2, 6, 1, 4, 9, 3, 7]
array: [8, 0, 5, 2, 6, 1, 4, 9, 3, 7]