LinkedList通常使用的遍历方式有两种:for循环遍历,即调用get方法;还有就是迭代器循环。建议采用迭代器循环,这个网上有很多比较数据说明,下面简单通过源码看一下原因。本文代码jdk8。
1:for循环遍历时调用get方法,下面看一下源代码
public E get(int index) { checkElementIndex(index); return node(index).item; }
Node<E> node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) { //判断是从头部开始查询还是尾部开始 Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } }java中LinkedList是一个双向列表,get方法查询某个位置的元素时,既可以从头开始,也可以从尾部开始,即使这样get方法遍历一半元素也需要n/2 + ... + 2 + 1次。
2:迭代器循环
private class ListItr implements ListIterator<E> { private Node<E> lastReturned = null; private Node<E> next; private int nextIndex; private int expectedModCount = modCount; ListItr(int index) { // assert isPositionIndex(index); next = (index == size) ? null : node(index);//index == 0就是从头开始 nextIndex = index; } public boolean hasNext() { return nextIndex < size; } public E next() { checkForComodification(); if (!hasNext()) throw new NoSuchElementException(); lastReturned = next; next = next.next;//索引位置的元素 nextIndex++;//位置索引,遍历的时候不会每次都从头开始查 return lastReturned.item; }
......
}
看一下LinkedList迭代器,每次都记录下次遍历元素位置以及元素节点,遍历一遍就是n次
知其然知其所以然,透过源码,我们就知道了LinkedList遍历差别的原因,这样才能更好运用。随便写写,有错误的地方还请指正。