Java自定义List如何不使用Collections.swap()实现随机打乱功能?
自定义链表随机重排解决方案
原有代码核心问题
- 自定义
List类的length()方法存在缺陷:- 调用时未重置
current指针到链表头部,若调用前current不在首节点,返回的长度值错误 - 计数遍历后
current会被置为null,后续调用getContent()只能拿到空值 - 没有保留调用前的
current指针位置,会破坏外部的指针状态
- 调用时未重置
shuffleList方法存在语法错误:代码中使用的mail1、pw1、mail2、pw2属于未定义变量- 指针移动逻辑混乱:遍历后没有正确重置指针位置,导致索引和节点无法对应
修复步骤
1. 先修复length()方法
public int length() { int count = 0; // 保存原有current位置,避免影响外部状态 ListNode originalCurrent = current; // 从链表头开始计数 toFirst(); while (hasAccess()) { count++; next(); } // 恢复原有current位置 current = originalCurrent; return count; }
2. 实现正确的随机重排逻辑
我们采用直接交换节点存储的内容的方案,不需要调整链表的节点连接关系,也不需要额外实现节点交换方法,完全基于你现有List的公开API即可实现:
public static void shuffleList(final List<String[]> list) { int length = list.length(); // 空列表或仅1个元素无需重排 if (length <= 1) { return; } Random random = new Random(); // Fisher-Yates洗牌算法逻辑 for (int i = 0; i < length - 1; i++) { // 生成[i, length-1]区间的随机索引 int targetIndex = i + random.nextInt(length - i); // 定位到i位置,取出存储的内容 list.toFirst(); for (int j = 0; j < i; j++) { list.next(); } String[] contentI = list.getContent(); // 定位到随机目标位置,取出存储的内容 list.toFirst(); for (int j = 0; j < targetIndex; j++) { list.next(); } String[] contentTarget = list.getContent(); // 交换两个位置的内容 list.setContent(contentI); list.toFirst(); for (int j = 0; j < i; j++) { list.next(); } list.setContent(contentTarget); } }
内容的提问来源于stack exchange,提问作者neb737
相关产品推荐
相关产品推荐

