Java集合源码学习(5)_List接口的基础实现AbstractList

一:AbstractList介绍

AbstractList是List的接口的基础实现,继承了AbstractCollection类,实现了List接口;

1:该基础实现类简化了以"随机访问"数据结构存储元素(比如数组)的集合类的实现,他的一个子类AbstractSequentialList简化了以"顺序访问"数据结构存储元素(比如链表)的集合类的实现;
2:该类增加了一个抽象方法abstract public E get(int index);获取指定位置的元素;
   此外从AbstractCollection类继承了一个抽象方法abstract public int size()方法(实现了public abstract Iterator<E> iterator())
3:该类的一个私有类Itr实现了Iterator接口;一个私有类ListItr实现了ListIterator接口;
   iterator()方法返回的就是一个Itr类的实例(每次都会新建一个);listIterator()返回的就是一个ListIterator的实例(每次都会新建一个);这两个类的代码,之后会做分析;
4:对List相比Collection接口独有的方法进行了基础的实现,indexOf()、lastIndexOf()等查询方法是通过iterator()或者listIterator()返回的迭代器来实现的;
5:默认实现的set(int,E)、remove(int)、add(int,E)是不支持的
6:该类有一个类变量modCount,记录这个List被修改的次数。主要是用来使用Iterator遍历这个List的时候,如果发现其他线程修改了这个List,那么会抛出ConcurrentModificationException
因此,如果想要实现一个只读的List,只需要实现size()和get(int)两个抽象方法即可;
如果想要实现一个可变的List,还需要重写set(int,E)、remove(int)、add(int,E)

二:Iterator接口的实现Itr

private class Itr implements Iterator<E> {
	//调用next()方法时,返回的元素的index
	int cursor = 0;
	//上一次调用next或者previous方法返回的元素的位置
	int lastRet = -1;
	//该Iterator认为的所属的List的属性modCount正确的值;如果List被其他线程修改,modCount与该属性不一致就会抛出异常
	int expectedModCount = modCount;

	public boolean hasNext() {
        return cursor != size();
	}
	public E next() {
            checkForComodification();
	    try {
		E next = get(cursor);
		lastRet = cursor++;
		return next;
	     } catch (IndexOutOfBoundsException e) {
		checkForComodification();
		throw new NoSuchElementException();
	     }
	}
	public void remove() {
	    if (lastRet == -1)
			throw new IllegalStateException();
        checkForComodification();
	    try {
			//调用List的remove方法删除指定元素
			AbstractList.this.remove(lastRet);
			if (lastRet < cursor)
				cursor--;
			lastRet = -1;
			expectedModCount = modCount;
	    } catch (IndexOutOfBoundsException e) {
			throw new ConcurrentModificationException();
	    }
	}
	final void checkForComodification() {
	    if (modCount != expectedModCount)
			throw new ConcurrentModificationException();
	}
}

三:ListIterator接口的实现ListtItr

	private class ListItr extends Itr implements ListIterator<E> {
		//从第几个位置开始
		ListItr(int index) {
			cursor = index;
		}
		//往前是否还有元素
		public boolean hasPrevious() {
			return cursor != 0;
		}
		//获得当前位置的前一个元素
		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;
		}
		//设置当前元素的前一个操作的元素
		public void set(E e) {
			if (lastRet == -1)
				throw new IllegalStateException();
			checkForComodification();
			try {
				AbstractList.this.set(lastRet, e);
				expectedModCount = modCount;
			} catch (IndexOutOfBoundsException ex) {
				throw new ConcurrentModificationException();
			}
		}
		//当前元素设置为指定元素,当前位置+1
		public void add(E e) {
			checkForComodification();

			try {
				AbstractList.this.add(cursor++, e);
				lastRet = -1;
				expectedModCount = modCount;
			} catch (IndexOutOfBoundsException ex) {
				throw new ConcurrentModificationException();
			}
		}
	}

四:SubList

该类继承了AbstractList,表示父List在指定的fromIndex和toIndex之间的元素构成的子List。但是数据是和父List共享的,SubList修改时会影响到父List


五:AbstractSequentialList

这个类是AbstractList的子类,AbstractList没有具体实现 get(int index) , set(int index, E element) add(int index, E element)  and  remove(int index)等操作;
AbstractSequentialList基于listIterator()返回的迭代器来实现;
这个类里面listIterator()是一个抽象方法;
java doc推荐,如果是基于"顺序访问"的数据结构(比如链表)实现的List,都继承AbstractSequentialList而非AbstractList;
如果想要实现一个只读的List,只要实现listIterator()(实现hasNextnexthasPreviousprevious 和index)和size()方法即可;
如果想要实现一个可以修改的List,就要实现ListIterator的 remove add方法;
LinkedList就是直接实现了该类,这个类,后面再进行专门的学习



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值