解析java.util集合类源码(List和AbstractList篇)

时间:2021-06-27 17:01:00

接口List

有序的 collection(也称为 序列),作为Collection的子接口,继承了所有Collection中的方法,同时对集合进行限制

1.允许集合中的元素重复

2.提供了特殊的迭代器,成为ListIterator,该迭代器实现了一些元素的插入和替换

3.提供搜索元素和插入、删除等方法

在Collection中接口有的方法不在描述请查看上篇博客点击打开链接


boolean addAll(int index, Collection<? extends E> c)

将指定的集合插入到该序列中的指定的index位置

E get(int index)

获取序列中指定位置的元素

E set(int index, E element)

用指定的元素替换序列中指定位置的元素

void add(int index, E element)

在序列指定位置中添加元素

E remove(int index)

移除序列中指定位置的元素

int indexOf(Object o)

获取指定元素第一次在序列中出现的位置

int lastIndexOf(Object o)

获取指定元素最后一次在序列中出现的位置

ListIterator<E> listIterator()

返回列表元素的列表迭代器(按适当顺序)

ListIterator<E> listIterator(int index)

返回列表元素的列表迭代器(按适当顺序),从指定的位置开始

subList(int fromIndex, int toIndex)

返回该序列中从fromIndex到toIndex中的一个子序列(子列表其实还是这个列表一部分,改变了会改变该序列)


抽象类AbstractList

提供List接口的实现方法,适合随机访问的数据存储(如数组)

public boolean add(E e) {
add(size(), e);
return true;
}
重写AbstractCollection中的add方法,调用自身子类实现的add(int index, Object e)方法

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();
}
set.add.remove三个已经实现的方法,抛出了不可操作的异常,为什么这三个类实现了,但是只抛出了不可操作的异常,上边的get方法确实抽象了出来,一开始不太明白,后来想起来java api里的一句话

java api:

要实现不可修改的列表,编程人员只需扩展此类,并提供 get(int)size() 方法的实现。

要实现可修改的列表,编程人员必须另外重写 set(int, E) 方法(否则将抛出 UnsupportedOperationException)。如果列表为可变大小,则编程人员必须另外重写add(int, E)remove(int) 方法。

此类是抽象类,不仅仅用于java 源码当中,当编程人员需要用到此类时候,可以根据需求重写set add 和 remove方法,如果没有需求及不需要重写此方法,这时候,在代码中使用set add 或 remove 方法时候,就会抛出异常。

若将set add 和remove三个方法写成abstract 抽象的,编程人员需要用到 add 方法,却不使用另外两个方法,这时候因为三个都是抽象的,所以都必须要实现,无用的代码太多。

同时,AbstractList中get方法强制性较高,也就是说使用AbstractList就必须实现get方法,但set add remove这三个带有index位置的方法确实强制性较低(set add remove 没有index位置的方法已经在AbstractCollection中实现),所以只有在需要的时候进行重写。

public int indexOf(Object o) {
ListIterator<E> e = listIterator();
if (o==null) {
while (e.hasNext())
if (e.next()==null)
return e.previousIndex();
} else {
while (e.hasNext())
if (o.equals(e.next()))
return e.previousIndex();
}
return -1;
}

获得object对象在列表中的位置,通过list Iterator()方法迭代循环列表,找到对象在列表中第一次出现的下标,返回下标值

 public int lastIndexOf(Object o) {
ListIterator<E> e = listIterator(size());
if (o==null) {
while (e.hasPrevious())
if (e.previous()==null)
return e.nextIndex();
} else {
while (e.hasPrevious())
if (o.equals(e.previous()))
return e.nextIndex();
}
return -1;
}
获得object对象在列表中组后出现的位置,indexOf(Object o)方法


public void clear() {
removeRange(0, size());
}
调用本抽象类中的removeRange方法,从0开始清空size()个,就是讲列表中的元素全部清空(removeRange方法在下面做介绍)


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();
}
}
通过ListIterator迭代器循环删除每个元素

public boolean addAll(int index, Collection<? extends E> c) {
boolean modified = false;
Iterator<? extends E> e = c.iterator();
while (e.hasNext()) {
add(index++, e.next());
modified = true;
}
return modified;
}
将集合添加到指定位置,迭代循环Collection,调用add方法将Collection中的每个元素添加到列表中,add(index,e)实在子类中实现的

public Iterator<E> iterator() {
return new Itr();
}

返回一个本类的普通的迭代器

 public ListIterator<E> listIterator() {
return listIterator(0);
}

 public ListIterator<E> listIterator(final int index) {
if (index<0 || index>size())
throw new IndexOutOfBoundsException("Index: "+index);

return new ListItr(index);
}


返回一个本类的List迭代器

Itr和ListItr(index)都是内部类

内部类在下篇博客分析


public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<E>(this, fromIndex, toIndex) :
new SubList<E>(this, fromIndex, toIndex));
}

若此列表实现了RandomAccess接口,则返回一个RandomAccessSubList子列表,否则返回一个SubList子列表

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;
Iterator<E> i = iterator();
while (i.hasNext()) {
E obj = i.next();
hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
}
return hashCode;
}
用列表的hash算法算出该列表的hashCode

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();
}
}
用ListIterator迭代器删除一定范围的元素


protected transient int modCount = 0;
记录修改次数,modCount在AbstractList中定义为结构话改变List的次数,这里是为了在Iterator和ListIterotor访问List时出现并发访问,在下篇的内部类中有说