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

接口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时出现并发访问,在下篇的内部类中有说


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值