大纲
List接口
存取顺序一致,有索引,允许重复
类声明
public interface List<E> extends Collection<E>
特有方法
所有通过索引操作的方法都要注意其索引的范围,否则容易导致发生 IndexOutOfBoundsException
void add(int index, E element); // 向指定索引处增加元素 0 <= index <= size
boolean addAll(int index, Collection<? extends E> c); // 向指定索引处增加集合中的所有元素 0 <= index <= size
E remove(int index); // 删除指定索引位置的元素 0 <= index < size
E set(int index, E element); // 修改指定索引处的元素 0 <= index < size
E get(int index); // 获取指定索引处的元素 0 <= index < size
int indexOf(Object o); // 获取指定元素第一次出现的索引,若不存在则返回-1
int lastIndexOf(Object o); // 获取指定元素最后一次出现的索引,若不存在则返回-1
List<E> subList(int fromIndex, int toIndex); // 返回集合中从fromIndex(含)到toIndex(不含)的视图,与原集合会相互影响
ListIterator<E> listIterator(); // 返回listIterator hasPrevious()、previous()、add(E e);
ListIterator<E> listIterator(int index); // 从指定索引处开始返回listIterator 0 <= index <= size
// jdk1.8新增方法
default void sort(Comparator<? super E> c){} // 根据Comparator来排序数组
default void replaceAll(UnaryOperator<E> operator) {} // 将该列表的每个元素替换为该运算符应用于该元素的结果
Collection 方法
重写了 Collection
的抽象方法和一个默认方法
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] a);
boolean add(E e);
boolean remove(Object o);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
void clear();
boolean equals(Object o);
int hashCode();
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.ORDERED);
}
上诉可以看到,List
将 Collection
中的抽象方法重新定义了一遍,既然一样为什么要写重复的代码?
Collection 表示的是一组共性集合, 没有特点 (是否排序, 是否去重)。而List、Set之类的各有其特点,重新定义可以针对其特点写不同的注释,并且也可以一目了然的知道该类有哪些方法,在调用链上更加明了清晰
AbstractList抽象类
实现了 List
的部分方法,iterator
和 size
没有实现
类声明
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
主要字段
// 维护了集合被修改的次数
protected transient int modCount = 0;
构造函数
protected AbstractList() {}
List 方法实现
// 限定了add、set、remove操作, 由子类实现
public void add(int index, E element) { throw new UnsupportedOperationException();}
public E set(int index, E element) { throw new UnsupportedOperationException();}
public E remove(int index) { throw new UnsupportedOperationException();}
// 获取指定角标的元素,未实现
abstract public E get(int index);
// 从前往后找,获取指定元素在集合中第一次出现的索引,若不存在则返回-1
public int indexOf(Object o) {
ListIterator<E> it = listIterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return it.previousIndex();
} else {
while (it.hasNext())
if (o.equals(it.next()))
return it.previousIndex();
}
return -1;
}
// 从后往前找,获取指定元素在集合中第一次出现的索引,若不存在则返回-1
public int lastIndexOf(Object o) {
ListIterator<E> it = listIterator(size());
if (o==null) {
while (it.hasPrevious())
if (it.previous()==null)
return it.nextIndex();
} else {
while (it.hasPrevious())
if (o.equals(it.previous()))
return it.nextIndex();
}
return -1;
}
// 在集合末尾添加元素, add由子类实现
public boolean add(E e) {
add(size(), e);
return true;
}
// 向指定索引处增加集合中的所有元素, add由子类实现
public boolean addAll(int index, Collection<? extends E> c) {
// 索引检查 index < 0 || index > size()
rangeCheckForAdd(index);
boolean modified = false;
for (E e : c) {
add(index++, e);
modified = true;
}
return modified;
}
// 调用 removeRange
public void clear() {
removeRange(0, size());
}
// 获取迭代器
public Iterator<E> iterator() {
return new Itr();
}
// 获取list迭代器
public ListIterator<E> listIterator() {
return listIterator(0);
}
// 从指定索引获取迭代器
public ListIterator<E> listIterator(final int index) {
// 索引检查 index < 0 || index > size()
rangeCheckForAdd(index);
return new ListItr(index);
}
// 截取集合,返回的集合与原集合相互影响
public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<>(this, fromIndex, toIndex) :
new SubList<>(this, fromIndex, toIndex));
}
// 两个个内部类
private class Itr implements Iterator<E> {}
private class ListItr extends Itr implements ListIterator<E> {}
// 在AbstractList类下的两个类,**不是内部类
class SubList<E> extends AbstractList<E> {}
class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {}
Collection 方法实现
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
ListIterator<E> e1 = listIterator();
ListIterator<?> e2 = ((List<?>) o).listIterator();
while (e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
public int hashCode() {
int hashCode = 1;
for (E e : this)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
return hashCode;
}
特有方法
// 范围删除,包含 fromIndex,不包含 toIndex
protected void removeRange(int fromIndex, int toIndex) {
ListIterator<E> it = listIterator(fromIndex);
for (int i=0, n=toIndex-fromIndex; i<n; i++) {
it.next();
it.remove();
}
}
内部类 Itr
AbstractList通过使用两个内部类 Itr
和 ListItr
实现集合的遍历
private class Itr implements Iterator<E> {
// 用来标识当前所要遍历元素的下标
int cursor = 0;
// 用来记录调用next调用后所指向的下标,调用remove后会重置为-1
int lastRet = -1;
// 用来标识最初的modCount(来至于外部类AbstractList),调用迭代器的修改方法会重新赋值
int expectedModCount = modCount;
// 每次遍历时add/remove都会修改modCount,若检测到expectedModCount和modCount不一致就会抛异常
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
// 判断是否有下一个元素
public boolean hasNext() {
return cursor != size();
}
// 获取下一个元素,先检测modCount是否被修改,获取元素,修改lastRet和cursor
public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
// 删除元素,删除前必须调用next()方法,删除的是当前元素也就是角标为lastRet的元素
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
// 调用子类实现的remove方法删除元素,并给cursor、lastRet和expectedModCount重新赋值
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
}
内部类 ListItr
ListItr
继承了 Itr
实现了 ListIterator
, ListIterator
接口是对 Iterator
的扩展,使迭代器不仅能向后迭代也能向前迭代,还能获取当前元素和将要遍历元素的下标,也可对元素进行增、删、改操作
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
cursor = index;
}
// 是否有前一个元素
public boolean hasPrevious() {
return cursor != 0;
}
// 获取前一个元素并修改cursor和lastRet
public E previous() {
checkForComodification();
try {
int i = cursor - 1;
E previous = get(i);
lastRet = cursor = i;
return previous;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
// 获取下一个将要迭代的元素角标
public int nextIndex() {
return cursor;
}
// 获取当前元素的角标
public int previousIndex() {
return cursor-1;
}
// 调用子类实现的set方法修改元素并给并给expectedModCount重新赋值
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.set(lastRet, e);
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
// 调用子类实现的add方法修改元素并给并给cursor、lastRet和expectedModCount重新赋值
public void add(E e) {
checkForComodification();
try {
int i = cursor;
AbstractList.this.add(i, e);
lastRet = -1;
cursor = i + 1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
SubList
SubList
调用subList方法所创建的对象,所引用的还是原数组
class SubList<E> extends AbstractList<E> {
// 用于存放原List的引用
private final AbstractList<E> l;
// 子List在原List中的开始位置
private final int offset;
// 子List的大小
private int size;
// 构造函数初始化
SubList(AbstractList<E> list, int fromIndex, int toIndex) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > list.size())
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
l = list;
offset = fromIndex;
size = toIndex - fromIndex;
this.modCount = l.modCount;
}
// 下标检测
private void rangeCheck(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
// add下标检测
private void rangeCheckForAdd(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
// 修改检测,判断原集合中的modCount和SubList中的modCount是否相等
private void checkForComodification() {
if (this.modCount != l.modCount)
throw new ConcurrentModificationException();
}
// 调用原集合的set方法 offset+index
public E set(int index, E element) {
rangeCheck(index);
checkForComodification();
return l.set(index+offset, element);
}
// 调用原集合的get方法 offset+index
public E get(int index) {
rangeCheck(index);
checkForComodification();
return l.get(index+offset);
}
// 子集合的大小
public int size() {
checkForComodification();
return size;
}
// 调用原集合的add方法 offset+index,并修改this.mod和size
public void add(int index, E element) {
rangeCheckForAdd(index);
checkForComodification();
l.add(index+offset, element);
this.modCount = l.modCount;
size++;
}
// 调用原集合的remove方法 offset+index,并修改this.mod和size
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = l.remove(index+offset);
this.modCount = l.modCount;
size--;
return result;
}
// 调用原集合的removeRange方法
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
l.removeRange(fromIndex+offset, toIndex+offset);
this.modCount = l.modCount;
size -= (toIndex-fromIndex);
}
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
int cSize = c.size();
if (cSize==0)
return false;
checkForComodification();
l.addAll(offset+index, c);
this.modCount = l.modCount;
size += cSize;
return true;
}
public Iterator<E> iterator() {
return listIterator();
}
public ListIterator<E> listIterator(final int index) {
checkForComodification();
rangeCheckForAdd(index);
// 匿名内部类 对ListIterator实现
return new ListIterator<E>() {
// ...
};
}
// 套娃subList
public List<E> subList(int fromIndex, int toIndex) {
return new SubList<>(this, fromIndex, toIndex);
}
// 异常消息
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
}
RandomAccessSubList
RandomAccess
是一个标记接口,表明实现这个接口的 List 集合是支持快速随机访问,使用for循环遍历效率会高于迭代器遍历
class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
super(list, fromIndex, toIndex);
}
public List<E> subList(int fromIndex, int toIndex) {
return new RandomAccessSubList<>(this, fromIndex, toIndex);
}
}