Java之集合(五)LinkedList

  转载请注明源出处:http://www.cnblogs.com/lighten/p/7298017.html

1.前言

  Java中另一个常见的list就是本章将要讲的LinkedList。ArrayList的实现方式是数组,而LinkedList的实现方式是链表。两者在性能上有着明显的不同,之前讲过ArrayList的特点就是易于查找,弱于插入,而LinkedList正好相反。这些都是和其数据结构有关,具体使用哪个,需要看操作数组的主要方向是查找还是插入了。

2.AbstractSequentialList

  LinkedList并没有直接继承自AbstractList,而是继承自抽象父类AbstractSequentialList,其是继承自AbstractList的。AbstractSequentialList出现的原因在于其较于AbstractList对于"random access"(随机访问)方面更有优势。其只定义了如下方法:

  这些都是针对于链表结构的相关方法,而具体实现不像ArrayList的那样直接操作数组的下标(链表没有下标)。这些实现都是通过listIterator这个抽象方法完成的:

  其它方法就不再一一列出,顺带一提的是,其返还的迭代器就是ListIterator。这些就是AbstractSequentialList的全部内容了。

3LinkedList

  LinkedList继承自AbstractSequentialList,同时实现了List、Deque和Cloneable接口。其结构也一样的简单明了。数据结构如下:

  一个元素个数,一个头结点,一个尾结点。由于是链表,所以其是不需要扩容的,先看看Node的相关结构吧。

  很简单的结构,前一个结点的引用,下一个结点的引用和本结点的内容。这是一个双向链表。

  这是一个简单的插入到最前的一个实现:获取当前第一个元素,生成插入元素,替换成头结点。如果当前第一个元素为null,尾结点自然也就是头结点了,否者原头结点持有插入在其前面的结点的引用。其它的操作也基本与此类似,不再进行叙述,最后会给出一个图来看其操作。

  有意思的是LinkedList和ArrayList一样并没有使用父类的方法,而是重写了一套。所以其并没有使用迭代器完成get,remove等操作。

  node方法做了一点小优化:

  根据结点位置是在前半还是后半决定是顺序遍历还是逆序遍历,这样尽可能的减少遍历次数。

  最后看看迭代器,其实也没什么可看的了:

  定位到指定结点位置,然后对其进行操作罢了。逆序的迭代器实现就更简单了:

  最后值得一提的是,LinkedList并没有像ArrayList一样重写了SubList方法,所以其使用的还是抽象父类AbstractList实现的方法。

4.示意图

  移除操作类似,这里不再给出示意图。

 

posted @ 2017-08-07 10:46  dark_saber  阅读(325)  评论(0编辑  收藏  举报