为什么我们不能手动迭代LinkedList?

时间:2018-06-13 12:02:11

标签: java doubly-linked-list

LinkedList是一种数据结构,其中每个元素都与一个指向其下一个元素的链接相结合。

因此,从理论上讲,这个数据结构是为了在执行任何操作时(无论是删除你当前所在的元素除外)在任何方向上自由迭代列表。

但是,在申请中,情况并非如此。从LinkedList返回迭代器受一般Iterator规则的约束(即迭代时不进行修改),甚至创建ListIterator,改进的Iterator,允许修改下一个/上一个迭代器的元素,让你动态前进/后退,仍有严重的局限性:

如果您当前不在列表的开头,则无法从列表的开头删除元素,也不能将元素添加到列表的末尾,除非您当前在那里。

那么,有没有办法在对列表进行任何修改时自由迭代LinkedList?如果没有,为什么不存在呢?难道它不应该是实现它的数据结构的主要目标之一吗?

4 个答案:

答案 0 :(得分:3)

此行为并非特定于LinkedList。当您使用List迭代List(任何ListIterator)时,您只能在迭代器的当前位置进行结构更改(添加或删除元素)。否则,在List结构更改后继续使用迭代器可能会产生意外结果。

要将元素添加到LinkedList的开头或结尾,您可以使用addFirstaddLast方法。您无需迭代List即可。

ListIterator实例维护一个状态,允许它定位下一个和前一个元素以及支持其他操作(删除当前元素,在当前位置添加元素)。如果您通过ListListIterator进行结构更改,则迭代器的状态可能会变为无效,从而导致意外结果。因此,必须通过ListIterator进行所有结构更改。

我想LinkedList类可以提供更复杂的迭代器的实现,它支持addFirstaddLast等操作。我不确定本来会有多大用处,以及它是否能证明增加的复杂性。

答案 1 :(得分:3)

所有迭代器失败的选择是一个设计决定,仅此而已。

如果您认为可以使用它,那么您无需停止接受代码并从中开始构建NotSoFailFastIterator。但是,我认为一旦你看到它的行为及其在使用场景中的结果,你会迅速恢复使用它,其中真的在你的迭代器的底层列表上发生了很多并发活动。

答案 2 :(得分:0)

如果要自由迭代使用数组或列表。链接列表旨在遍历并访问在将内存动态分配给数据时有用的数据。

答案 3 :(得分:0)

如果您有链接列表数据结构,则可以在光标指向要添加或删除的右侧节点时在特定节点上添加或删除。

  

将指定的元素插入列表(可选操作)。该   元素将紧接在元素之前插入   由next()返回,如果有的话,在元素之后   如果有的话,由previous()返回。之前插入了新元素   隐式游标:对next的后续调用不受影响,   并且对previous的后续调用将返回新元素。 (这个   呼叫增加一个呼叫返回的值   nextIndex或previousIndex。)

ListIterator

相反,如果它是一个数组结构,那么你可以通过索引访问,并且可以通过数组的长度在特定索引处添加或删除。 ArrayList做到了。