1. 概述

在使用 Java 时,高效地遍历集合是常见的需求。在处理列表时,ListIterator 接口为双向遍历提供了强大的工具。然而,在某些情况下,我们需要将 ListIterator 重置到列表的开头。

本教程将探讨在 Java 中以各种方式重置 ListIterator 到列表开始的方法。

2. 问题介绍

通常,我们可以通过一个例子来理解这个问题。

假设我们有一个字符串列表:

List<String> MY_LIST = List.of("A", "B", "C", "D", "E", "F", "G");

然后,我们可以通过 MY_LIST.listIterator() 获取 MY_LISTListIterator,并通过调用 ListIteratornext() 方法进行遍历。

有时,我们可能想要将 ListIterator 对象重置为再次指向列表中的第一个元素之前的位置,就像它刚创建时一样。

接下来,我们将研究解决这个问题的不同方法,并利用单元测试断言来验证每个解决方案是否给出了预期的结果。

3. 创建新的 ListIterator

我们知道,当我们创建一个新的 ListIterator 对象时,它会指向目标列表的开始。因此,最简单的重置 ListIterator 实例的方法就是重新赋值给一个新的 ListIterator

让我们编写一个测试,检查这个想法是否按预期工作:

ListIterator<String> lit = MY_LIST.listIterator();
lit.next();
lit.next();
lit.next();
lit.next();

lit = MY_LIST.listIterator();

assertFalse(lit.hasPrevious());
assertEquals("A", lit.next());

如测试所示,我们创建了一个 ListIterator lit,并调用了 lit.next() 四次。当我们想要重置 lit 时,我们创建了一个新的 ListIterator 实例,并将其重新分配给 lit

然后,我们通过两个断言验证 lit 是否成功重置:

  • lit.hasPrevious() 返回 false
  • lit.next() 应该是 MY_LIST 中的第一个元素(“A”)

如果运行这个测试,它会通过。所以,创建一个新的 ListIterator 解决了我们的问题。

4. 向后迭代到列表的开头

创建新的 ListIterator 可以快速导航到列表的开头,但我们会得到一个新的 ListIterator 对象。有时,我们希望保留原始的 ListIterator 对象,并将指针移到列表的开始。如果是这样,我们可以利用 ListIterator 的双向遍历特性,向后迭代到列表的开头

接下来,让我们编写一个测试来看看如何实现这一点:

ListIterator<String> lit = MY_LIST.listIterator();
lit.next();
lit.next();
lit.next();
lit.next();

while (lit.hasPrevious()) {
    lit.previous();
}

assertFalse(lit.hasPrevious());
assertEquals("A", lit.next());

正如我们所见,我们通过一个 while 循环实现了向后的迭代【注:链接到 Java 中的 while 循环相关教程】。

如果运行这个测试,它会通过。所以,它完成了任务。

值得注意的是,由于这种方法是从当前位置向后迭代到列表的开头,如果列表中的元素数量很大,这可能会很慢

5. 总结

在这篇文章中,我们探讨了两种将 ListIterator 重置到列表开头的方法。

如果需要保留原始 ListIterator 对象,我们可以向列表头部后退。否则,创建一个新的 ListIterator 是最直接的解决方案。

一如既往,本文示例的完整代码可在 GitHub 上找到。