简体   繁体   English

Java LinkedList ListIterator行为

[英]Java LinkedList ListIterator behavior

I was working with a java.util.ListIterator on a java.util.LinkedList expecting it to work like in this pseudocode: 我正在使用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

But the order is like this: 但是顺序是这样的:

iterator.next is 1
iterator.next is 2
iterator.prev is 2
iterator.next is 2

I couldn't believe that this is the way it works, so I created a test, but it produces the same output. 我不敢相信这就是它的工作方式,所以我创建了一个测试,但是它产生了相同的输出。 So I had a closer look at the definition of ListIterator which of course is: 因此,我仔细研究了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.

So the implementation is correct, but I remain with the question why they have chosen this behavior? 因此实施是正确的,但我仍然要问他们为什么选择这种行为? Wouldn't it be much more intuitiv the way i got it? 我的理解方式会更直观吗?

Here is the code of the test: 这是测试的代码:

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());
    }
}

It is useful to imagine that iterators in Java never points to the specific element, but either before the first element, in the middle between two elements or just after the last element. 可以想象Java中的迭代器从不指向特定元素,而是指向第一个元素之前,两个元素之间的中间或最后一个元素之后。

So, when iterator created, it looks like 因此,当创建迭代器时,它看起来像

 1 2 3 4
^

When you call next , 1 is returned and iterators moves forward: 当您调用next ,返回1 ,并且迭代器向前移动:

 1 2 3 4
  ^    

When you call next again, 2 is returned and iterators moves forward: 当您再次调用next时,将返回2并且迭代器向前移动:

 1 2 3 4
    ^

When you call prev , 2 is returned and iterators moves backward: 调用prev ,将返回2 ,并且迭代器向后移动:

 1 2 3 4
  ^    

So the next call to next will return 2 . 所以,下次调用next将返回2

Notice that there is no way to get "current" value of the iterator. 请注意,无法获取迭代器的“当前”值。 The only way to get the value is to move the iterator. 获得值的唯一方法是移动迭代器。

The other way of implementing iterators we could see in C++. 我们可以在C ++中看到的另一种实现迭代器的方式。 To use C++ iterator we need three separate actions: retrieve current value, check that there are move values to retrieve and move iterator. 要使用C ++迭代器,我们需要三个单独的操作:检索当前值,检查是否存在要检索和移动迭代器的移动值。 While java approach needs only two actions: check that there are move values to retrieve and get-value-and-move-iterator. 尽管Java方法仅需要执行两个操作:检查是否有要检索的移动值以及get-value-move-iterator。 So it is simpler to implement custom iterator in Java than in C++. 因此,在Java中实现自定义迭代器比在C ++中实现更简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM