关于java集合框架中AbstractSequentialList类的理解

LinkedList是AbstractSequentialList的子类,而ArrayList是AbstractList的子类,AbstractSequentialList也是AbstractList的子类。编程

AbstractSequentialList的API文档

这个类提供了一个基本的List接口实现,为实现序列访问的数据储存结构的提供了所须要的最小化的接口实现。对于支持随机访问数据的List好比数组,应该优先使用AbstractListapi

这里是与随机访问类AbstractList类中相对的另外一套系统,采用的是在迭代器的基础上实现的get、set、add和remove方法数组

为了实现这个列表。仅仅须要拓展这个类,而且提供ListIterator和size方法。 
对于不可修改的List,编程人员只须要实现Iterator的hasNext、next和hasPrevious、previous和index方法 
对于可修改的List还须要额外实现Iterator的的set的方法 
对于大小可变的List,还须要额外的实现Iterator的remove和add方法dom


AbstractSequentiaList和RandomAccess主要的区别是AbstractSequentiaList的主要方法都是经过迭代器实现的。而不是直接实现的(不经过迭代器,好比ArrayList实现的方式是经过数组实现的。)所以对于一些能够提供RandomAccess的方法,直接使用方法可能更快。由于迭代器移动须要必定代价。源码分析

源码分析

AbstractSequentialList方法的实现并无特别须要注意的地方。主要是由于因为大部分的方法均是经过listIterator(int)的方法实现。可是listIterator(int)方法是一个抽象方法,基本实现只能从LinkedList中分析。 
这里简单的分析一些编程技巧。spa

 1 public E set(int index, E element) {
 2         try {
 3             ListIterator<E> e = listIterator(index);
 4             E oldVal = e.next();
 5             e.set(element);
 6             return oldVal;
 7         } catch (NoSuchElementException exc) {
 8             throw new IndexOutOfBoundsException("Index: "+index);
 9         }
10     }
11     public E remove(int index) {
12         try {
13             ListIterator<E> e = listIterator(index);
14             E outCast = e.next();
15             e.remove();
16             return outCast;
17         } catch (NoSuchElementException exc) {
18             throw new IndexOutOfBoundsException("Index: "+index);
19         }
20     }

set和remove方法返回了以前的oldVal,这样能够用于一些其余的操做。code

 1 public boolean addAll(int index, Collection<? extends E> c) {
 2         try {
 3             boolean modified = false;
 4             ListIterator<E> e1 = listIterator(index);
 5             Iterator<? extends E> e2 = c.iterator();
 6             while (e2.hasNext()) {
 7                 e1.add(e2.next());
 8                 modified = true;
 9             }
10             return modified;
11         } catch (NoSuchElementException exc) {
12             throw new IndexOutOfBoundsException("Index: "+index);
13         }
14     }

首先代码很清晰。只须要说明三点: 
一个问题是迭代器e2并非要求是ListIterator,而仅仅是Iterator。换句话说并不对容器类型作要求。这也是利用了迭代器的优势之一。 
第二个问题是这里设定了一个modified的变量。用来表示原表是否被更改。这样即便更改失败了,也能够经过返回值来判断是否对原进行了修改。blog

1 ListIterator<E> e1 = listIterator(index);
2 Iterator<? extends E> e2 = c.iterator();

第三个问题是通用的问题,首先是这里全部的方法都采用了这样的结构接口

1 try {
2 } catch (NoSuchElementException exc) {
3       throw new IndexOutOfBoundsException("Index: "+index);
4 }

这里将一个RuntimeException的未检查错误转换成了一个检查错误IndexOutOfBoundsException而后抛出。根据我目前查到的解释。大部分是说这样作是为了帮助将编程人员更好的定位问题。element

相关文章
相关标签/搜索