设为首页 加入收藏

TOP

【Java深入研究】2、LinkedList源码解析(四)
2017-10-13 10:03:50 】 浏览:7875
Tags:Java 深入 研究 LinkedList 源码 解析
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
首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇解决code唯一码(java)简便方法 下一篇【算法】1、快速排序

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目