为何ListIterator正向遍历未输出新增元素B2?技术求解
问题解答:ListIterator添加元素后正向遍历无新元素的原因
首先贴出你的代码:
public static void main(String[] args) { List<String> list = Arrays.asList("A", "B", "C", "D"); list = new ArrayList<>(list); ListIterator<String> li = list.listIterator(); String word; while (li.hasNext()) { word = li.next(); System.out.print(word + '\t'); if (word.equals("B")) li.add("B2"); } System.out.println(); while (li.hasPrevious()) { word = li.previous(); System.out.print(word + '\t'); if (word.equals("C")) li.add("C2"); } }
你的疑惑核心是:为什么正向遍历遇到"B"添加"B2"后,输出里没有"B2"?这确实和ListIterator的next()、previous()以及add()方法的协作逻辑有关,咱们一步步理清楚:
1. 正向遍历的执行细节
初始时,List是[A, B, C, D],ListIterator的游标位于第一个元素A的前面(可以理解为游标在元素之间的间隙,初始位置是0)。
- 第一次调用
li.next():游标移动到A和B之间,返回A,输出A - 第二次调用
li.next():游标移动到B和C之间,返回B,输出B - 此时触发
li.add("B2"):根据ListIterator的规则,新元素会插入到当前游标所在的间隙(B和C之间),并且游标会移动到新元素B2的后面(也就是B2和C之间)。重点来了:add()方法有个关键特性——后续调用next()会跳过这个新添加的元素,而调用previous()才会返回它。 - 第三次调用
li.next():游标从B2和C之间移动到C和D之间,返回的是C(而不是B2),输出C - 第四次调用
li.next():游标移动到D的后面,返回D,输出D
所以正向遍历的输出自然是A B C D,看不到B2。
2. 反向遍历的执行细节
正向遍历结束后,游标在D的后面。反向遍历用hasPrevious()检查是否有前一个元素:
- 第一次
li.previous():游标从D后面移动到C和D之间,返回D,输出D - 第二次
li.previous():游标移动到B2和C之间,返回C,输出C;此时触发li.add("C2"),新元素插入到游标当前位置(B2和C之间),游标移动到C2后面(C2和C之间) - 第三次
li.previous():游标移动到B2和C2之间,返回C2,输出C2 - 第四次
li.previous():游标移动到B和B2之间,返回B2,输出B2 - 第五次
li.previous():游标移动到A和B之间,返回B,输出B - 第六次
li.previous():游标移动到A前面,返回A,输出A
这就得到了你看到的反向输出:D C C2 B2 B A
总结
这个现象的核心不是next()和previous()本身的差异,而是ListIterator.add()方法的设计规则:
- 添加元素后,游标会落在新元素的后方
- 后续的
next()会继续遍历原来的下一个元素(不会返回新元素) - 后续的
previous()则会先返回新添加的元素
如果想要在正向遍历中输出B2,你需要在添加后手动调整游标位置(比如调用一次li.previous()再next()),不过通常不建议在遍历过程中修改列表后继续正向遍历,容易引发逻辑混乱。
内容的提问来源于stack exchange,提问作者hyena
相关产品推荐
相关产品推荐

