打乱集合元素
一、思路:
1.将集合元素提取出来形成一个List列表;
2.使用Map记录List列表中元素的位置,比如Map<元素,位置>;
3.根据Map集合的大小,定义一个令牌桶,桶里面的令牌即是编号(也就是位置);
4.随机从令牌桶中获取一个令牌;
5.循环遍历Map集合,如果Map集合里面的元素的位置和令牌(编号)是一样的,则继续下一次循环,重复步骤5;
6.直至元素位置和令牌不一致,将Map集合中元素的原位置替换为令牌(编号),并将令牌从令牌桶中移除。重复步骤5和步骤6,将Map集合里面的元素的位置全部替换;
7.对Map集合按value值进行排序并提取key值形成新的List列表,即得到打乱后的元素列表了。
二、代码如下:
package cd.letcode; import java.util.*; import java.util.stream.Collectors; /** * @author YouTh * @date 2025/10/26 16:24 * @description 将一个集合元素打乱 */ public class DisruptList <T> { // Map<原始数据,位置> private Map<T, Integer> originData = new HashMap<>(); // 令牌桶 private List<Integer> bucket = new ArrayList<>(); private static final Random RANDOM = new Random(); public DisruptList(List<T> data) { for (int i = 0; i < data.size(); i++) { this.originData.put(data.get(i), i); } this.generateBucket(); } /** * @Author: YouTh * @Date: 2025/10/26 17:00 * @Description: 生成令牌桶 * @param : * @return: void */ private void generateBucket() { for (int i=0; i<originData.size(); i++) { bucket.add(i); } } /** * @Author: YouTh * @Date: 2025/10/26 16:52 * @Description: 根据Map的value进行升序排序 * @param : * @return: void */ private void orderList() { originData = this.originData.entrySet() .stream() .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new )); } /** * @Author: YouTh * @Date: 2025/10/26 17:00 * @Description: 给集合元素重新安排令牌(序号) * @param : * @return: java.util.List<T> */ public List<T> disruptList() { for (int i=0; i<originData.size(); i++) { T element = (T) originData.keySet().toArray(new Object[0])[i]; int eleIndex = originData.get(element); while (bucket.size() >1) { int bucketIndex = RANDOM.nextInt(bucket.size()); if (bucketIndex == eleIndex) { continue; } // 更新元素的令牌(序号) originData.put(element, bucketIndex); // 移除已被使用的令牌 bucket.remove(bucketIndex); break; } } orderList(); return this.originData.keySet().stream().toList(); } public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); list.add("D"); list.add("E"); list.add("F"); DisruptList<String> disruptList = new DisruptList<>(list); List<String> result = disruptList.disruptList(); System.out.println("原始集合:" + list); System.out.println("打乱集合:" + result); } }
三、结果:

浙公网安备 33010602011771号