lic Object[] toArray() {
2 Object[] result = new Object[size];
3 int i = 0;
4 for (Entry<E> e = header.next; e != header; e = e.next)
5 result[i++] = e.element;
6 return result;
7 }
创建大小和LinkedList相等的数组result,遍历链表,将每个节点的元素element复制到数组中,返回数组。
toArray(T[] a)
1 public <T> T[] toArray(T[] a) {
2 if (a.length < size)
3 a = (T[])java.lang.reflect.Array.newInstance(
4 a.getClass().getComponentType(), size);
5 int i = 0;
6 Object[] result = a;
7 for (Entry<E> e = header.next; e != header; e = e.next)
8 result[i++] = e.element;
9 if (a.length > size)
10 a[size] = null;
11 return a;
12 }
先判断出入的数组a的大小是否足够,若大小不够则拓展。这里用到了发射的方法,重新实例化了一个大小为size的数组。之后将数组a赋值给数组result,遍历链表向result中添加的元素。最后判断数组a的长度是否大于size,若大于则将size位置的内容设置为null。返回a。
从代码中可以看出,数组a的length小于等于size时,a中所有元素被覆盖,被拓展来的空间存储的内容都是null;若数组a的length的length大于size,则0至size-1位置的内容被覆盖,size位置的元素被设置为null,size之后的元素不变。
为什么不直接对数组a进行操作,要将a赋值给result数组之后对result数组进行操作?
9、遍历数据:Iterator()
LinkedList的Iterator
除了Entry,LinkedList还有一个内部类:ListItr。
ListItr实现了ListIterator接口,可知它是一个迭代器,通过它可以遍历修改LinkedList。
在LinkedList中提供了获取ListItr对象的方法:listIterator(int index)。
1 public ListIterator<E> listIterator(int index) {
2 return new ListItr(index);
3 }
该方法只是简单的返回了一个ListItr对象。
LinkedList中还有通过集成获得的listIterator()方法,该方法只是调用了listIterator(int index)并且传入0。
二、ListItr
下面详细分析ListItr。
1 private class ListItr implements ListIterator<E> {
2 // 最近一次返回的节点,也是当前持有的节点
3 private Entry<E> lastReturned = header;
4 // 对下一个元素的引用
5 private Entry<E> next;
6 // 下一个节点的index
7 private int nextIndex;
8 private int expectedModCount = modCount;
9 // 构造方法,接收一个index参数,返回一个ListItr对象
10 ListItr(int index) {
11 // 如果index小于0或大于size,抛出IndexOutOfBoundsException异常
12 if (index < 0 || index > size)
13 throw new IndexOutOfBoundsException("Index: "+index+
14 ", Size: "+size);
15 // 判断遍历方向
16 if (index < (size >> 1)) {
17 // next赋值为第一个节点
18 next = header.next;
19 // 获取指定位置的节点
20 for (nextIndex=0; nextIndex<index; nextIndex++)
21 next = next.next;
22 } else {
23 // else中的处理和if块中的处理一致,只是遍历方向不同
24 next = header;
25 for (nextIndex=size; nextIndex>index; nextIndex--)
26 next = next.previous;
27 }
28 }
29 // 根据nextIndex是否等于size判断时候还有下一个节点(也可以理解为是否遍历完了LinkedList)
30 public boolean hasNext() {
31 return nextIndex != size;
32 }
33 // 获取下一个元素
34 public E next() {
35 checkForComodification();
36 // 如果nextIndex==size,则已经遍历完链表,即没有下一个节点了(实际上是有的,因为是循环链表,任何一个节点都会有上一个和下一个节点,这里的没有下一个节点只是说所有节点都已经遍历完了)
37 if (nextIndex == size)
38 throw new NoSuchElementException();
39 // 设置最近一次返回的节点为next节点
40 lastReturned = next;
41 // 将next“向后移动一位”
42 next = next.next;
43 // index计数加1
44 nextIndex++;
45 // 返回lastReturned的元素
46 return lastReturned.element;
47 }
48
49 public boolean hasPrevious() {
50 return nextIndex != 0;
51 }
52 // 返回上一个节点,和next()方法相似
53 public E previous() {
54 if (nextIndex == 0)
55 throw new NoSuchElementException();
56
57 lastReturned = next = next.previous;
58 nextIndex--;
59 checkForCom