java源码 -- AbstractList
Posted 王大军
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java源码 -- AbstractList相关的知识,希望对你有一定的参考价值。
AbstractList
AbstractList是实现List接口的抽象类,AbstractList抽象类与List接口的关系类似于AbstractCollection抽象类与Collection接口的关系。
AbstractList与AbstractCollection一样,也是通过提供一些方法的默认实现,简化我们编写List接口的列表类所需付出的努力。
实现列表类的需要记住:
方法
public boolean add(E e){}
public boolean add(E e) { add(size(), e); //通过调用add(int, E)方法进行添加 return true; }
//以下方法没有具体的实现,调用它时,抛出异常。
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); //无实现
// Search Operations搜索操作
//通过迭代器,循环找出内容 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; }
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;
}
// Bulk Operations 批量操作
//清空集合
public void clear() { 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(); } }
// 在集合中添加集合
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index); boolean modified = false; for (E e : c) { //foreach循环添加 add(index++, e); modi= true; } return mod }
// Iterators迭代器
两个迭代器实现类
AbstractList 中提供了两个迭代器的实现类,默认实现了迭代器接口,实现了对元素的遍历,它们就是Itr
和其子类 ListItr
,分别来了解一下。
Itr类,实现了Iterator接口,重写了next() 和 remove() 方法
private class Itr implements Iterator<E> { //游标 int cursor; //最近迭代的元素位置,每次使用完默认置为-1 int lastRet; //记录容器被修改的次数,值不相等说明有并发操作 int expectedModCount = modCount; //是否有下一个元素,就是游标是否不等于集合大小。等于的话 游标在集合末尾 则没有下一个元素 public boolean hasNext() { return cursor != size(); } public E next() { //检测是否有并发 checkForComodification(); try { int i = cursor; // 获取容器对应游标位置的元素 E next = get(i); //记录获取到的元素的索引 lastRet = i; //获取下一个元素的索引 cursor = i + 1; return next; } catch (IndexOutOfBoundsException var3) { checkForComodification(); throw new NoSuchElementException(); } }
public void remove() {
//还没读取元素就remove,报错
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
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();
}
}
ListItr 是 Itr 的子类,在Itr 的基础上增强了对元素的操作,多了指定索引的赋值,以及向前读取,add 和 set 的方法。
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 < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.set(lastRet, e); expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } 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(); } } }
AbstractList类中提供了两个方法,返回的各自实现的接口类型对象:
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); }
两个子类
AbstractList 提供了两个子类,可用于切分集合序列,这两个类是 SubList 和 RandomAccessSubList。
1. SubList 的内部实现和 AbstractList 很相似,无非是传递了两个变量,返回指定的fromIndex (含)和toIndex之间的列表部分的视图,初识位置和结束位置来截取集合。
2. RandomAccessSubList 是 SubList 的子类,内部实现直接沿用父类,只是实现了RandomAccess接口。
不一样的是,RandomAccessSubList 实现了一个接口RandomAccess,打开后发现是空的,没有任何实现。
它的作用是用于标识某个类是否支持 随机访问(随机访问,相对比“按顺序访问”)。一个支持随机访问的类明显可以使用更加高效的算法。例如遍历上,实现RandomAccess 接口的集合使用 get() 做迭代速度会更快,比起使用迭代器的话。
感谢:https://blog.csdn.net/u013164931/article/details/79640715
以上是关于java源码 -- AbstractList的主要内容,如果未能解决你的问题,请参考以下文章