AbstractList
前言: 本文所采用的jdk版本为:jdk1.8.0_111。
上图可以看出,AbstractList继承自AbstractCollection,并且实现了List接口,其子类中也包含着很多常用的List实现类,如ArrayList、LinkedList等。上一篇文章我们知道,AbstractCollection实现了除iterator 和size 以外的所有方法,那我们这一篇来看一下AbstractList中又实现了哪些方法。
上图是在eclipse中截的图,是AbstractList中所有的成员,我们可以看到除了常见的一些方法,其中还包含的内部迭代器类等。
一、实现的方法
1.1 add(E e)
public boolean add(E e) {
add(size(), e);
return true;
}
AbstractList中实现了add方法,该源码中可以看出,它调用了add(size(),e)方法,该方法是在List接口中定义的,用于list中向指定下标插入元素,这里该方法的意思自然是向列表末尾插入一个元素。
1.2 该类中默认不支持的方法
abstract public E get(int index);
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
上面4个方法中,我们又见到了熟悉的情况,本类中以上四个方法都不支持,但是第一个写成抽象方法,下面三个皆默认抛出异常,这种写法上篇文章提到过。
1.3 indexOf(Object o)
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;
}
这是一个索引方法,查找元素第一次出现的位置,源码中的迭代器要着重看一下,因为这里使用的是ListIterator迭代器,关于Iterator和ListIterator的区别,后面会单独写一篇文章来分析,这里仅用到的是ListIterator特有的一种功能,就是定位当前索引位置的功能,这是Iterator所没有的功能。
1.4 lastIndexOf(Object o)
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;
}
这个方法的功能是返回元素的最后一次出现的位置,这里运用的ListIterator的另一个功能——倒序迭代,这里采用倒序的形式,查找出的元素即是整体最后一次出现的位置。
1.5 clear()
public void clear() {
removeRange(0, size());
}
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();
}
}
这里重写了clear()方法,实际上不重写功能也可以实现,只是这里采用了ListIterator重新实现了功能,并且这里引出一个removeRange方法,源码中可以看出该方法可以自定义删除的开始和结束索引值,并在索引值内进行迭代删除元素。
1.6 addAll(int index, Collection<? extends E> c)
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index); //检查index是否合法,如果不合法,会报一个数组越界的错误的异常。
boolean modified = false;
for (E e : c) {
add(index++, e);
modified = true;
}
return modified;
}
将c的元素全部添加到集合中的指定位置。
1.7 迭代器
public Iterator<E> iterator() {
return new Itr();
}
public ListIterator<E> listIterator() {
return listIterator(0);
}
public ListIterator<E> listIterator(final int index) {
rangeCheckForAdd(index);
return new ListItr(index);
}
这三个方法实现了迭代器的定义,可以看出实际上list中是同时支持这两种迭代器的,并且,ListIterator 支持任意位置的索引。
1.8 subList(int fromIndex, int toIndex)
public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<>(this, fromIndex, toIndex) :
new SubList<>(this, fromIndex, toIndex));
}
该方法是用于返回指定索引值之间的list的映射,这里之所以指出是映射,是因为它得到的list并不是新的实例,而是在原来的基础上映射出来的,其所指向的内存还在原list上,所以注意,新的list如果修改的话,会影响原来的list的元素。故该方法慎用。
1.9 equals(Object o)
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());
}
这里重写了equals方法,从源码上分析可知,要使equals为true,要么其“==”相同,即同一个实例,要么就是他们中的每一个元素相同(要么同为null,要么元素的equals为true),此时equals方法才能为true。