我正在java.util.LinkedList上使用java.util.ListIterator,期望它像在这个伪代码中一样工作:
list = (1,2,3,4)
iterator.next should be 1
iterator.next should be 2
iterator.prev should be 1
iterator.next should be 2
但顺序是这样的:
iterator.next is 1
iterator.next is 2
iterator.prev is 2
iterator.next is 2
我无法相信这是它的工作方式,所以我创建了一个测试,但它产生了相同的输出。 所以我仔细研究了ListIterator的定义,当然是:
next()
Returns the next element in the list and advances the cursor position.
previous()
Returns the previous element in the list and moves the cursor position backwards.
所以实施是正确的,但我仍然怀疑为什么他们选择了这种行为?难道不是我得到它的方式更直接吗?
以下是测试代码:
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import java.util.LinkedList;
import java.util.ListIterator;
public class LinkedListTest {
ListIterator<Integer> iterator;
@Before
public void setUp() throws Exception {
LinkedList<Integer> list = new LinkedList<>();
for (int i = 1; i < 5; i++) {
list.add(i);
}
iterator = list.listIterator();
}
@Test
public void successfullTest() throws Exception
{
assertEquals(1, (int) iterator.next());
assertEquals(2, (int) iterator.next());
assertEquals(2, (int) iterator.previous());
assertEquals(2, (int) iterator.next());
assertEquals(3, (int) iterator.next());
assertEquals(4, (int) iterator.next());
}
@Test
public void failingTest() throws Exception
{
assertEquals(1, (int) iterator.next());
assertEquals(2, (int) iterator.next());
assertEquals(1, (int) iterator.previous());
assertEquals(2, (int) iterator.next());
assertEquals(3, (int) iterator.next());
assertEquals(4, (int) iterator.next());
}
}
答案 0 :(得分:5)
可以想象,Java中的迭代器永远不会指向特定元素,而是指向第一个元素之前,两个元素之间的中间或最后一个元素之后。
因此,当迭代器创建时,它看起来像
1 2 3 4
^
当您致电next
时,会返回1
并且迭代器会向前移动:
1 2 3 4
^
再次致电next
时,会返回2
并且迭代器会向前移动:
1 2 3 4
^
当你调用prev
时,会返回2
并且迭代器会向后移动:
1 2 3 4
^
因此,对next
的下一次调用将返回2
。
请注意,现在有办法获得&#34;当前&#34;迭代器的值。获取值的唯一方法是移动迭代器。
实现迭代器的另一种方法我们可以在C ++中看到。要使用C ++迭代器,我们需要三个单独的操作:检索当前值,检查是否有移动值来检索和移动迭代器。虽然java方法只需要两个动作:检查是否有要移动的移动值和get-value-and-move-iterator。因此,在Java中实现自定义迭代器比在C ++中实现更简单。