AbstractList

  AbstractList是实现List接口的抽象类,AbstractList抽象类与List接口的关系类似于AbstractCollection抽象类与Collection接口的关系。

  AbstractList与AbstractCollection一样,也是通过提供一些方法的默认实现,简化我们编写List接口的列表类所需付出的努力。

实现列表类的需要记住:

  1)要想实现一个不可修改的集合,只需要继承这个类,并且实现get(int)、size()方法;
  2)要想实现一个可以修改的集合,还必须重写set(int, E)方法,该方法默认抛出一个异常。如果集合是可动态调整大小的,还必须重写add(int, E),remove(int)方法。

方法

 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 提供了两个子类,可用于切分集合序列,这两个类是 SubListRandomAccessSubList

  1. SubList 的内部实现和 AbstractList 很相似,无非是传递了两个变量,返回指定的fromIndex (含)和toIndex之间的列表部分的视图,初识位置和结束位置来截取集合。

  2. RandomAccessSubList 是 SubList 的子类,内部实现直接沿用父类,只是实现了RandomAccess接口。

   不一样的是,RandomAccessSubList 实现了一个接口RandomAccess,打开后发现是空的,没有任何实现。

   它的作用是用于标识某个类是否支持 随机访问(随机访问,相对比“按顺序访问”)。一个支持随机访问的类明显可以使用更加高效的算法。例如遍历上,实现RandomAccess 接口的集合使用 get() 做迭代速度会更快,比起使用迭代器的话。

感谢:https://blog.csdn.net/u013164931/article/details/79640715

java源码 -- AbstractList的更多相关文章

  1. 如何阅读Java源码 阅读java的真实体会

    刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心.   说到技术基础,我打个比 ...

  2. Android反编译(一)之反编译JAVA源码

    Android反编译(一) 之反编译JAVA源码 [目录] 1.工具 2.反编译步骤 3.实例 4.装X技巧 1.工具 1).dex反编译JAR工具  dex2jar   http://code.go ...

  3. 如何阅读Java源码

    刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动.源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比方吧, ...

  4. Java 源码学习线路————_先JDK工具包集合_再core包,也就是String、StringBuffer等_Java IO类库

    http://www.iteye.com/topic/1113732 原则网址 Java源码初接触 如果你进行过一年左右的开发,喜欢用eclipse的debug功能.好了,你现在就有阅读源码的技术基础 ...

  5. Programming a Spider in Java 源码帖

    Programming a Spider in Java 源码帖 Listing 1: Finding the bad links (CheckLinks.java) import java.awt. ...

  6. 解密随机数生成器(二)——从java源码看线性同余算法

    Random Java中的Random类生成的是伪随机数,使用的是48-bit的种子,然后调用一个linear congruential formula线性同余方程(Donald Knuth的编程艺术 ...

  7. Java--Eclipse关联Java源码

    打开Eclipse,Window->Preferences->Java 点Edit按钮后弹出: 点Source Attachment后弹出: 选择Java安装路径下的src.zip文件即可 ...

  8. 使用JDT.AST解析java源码

    在做java源码的静态代码审计时,最基础的就是对java文件进行解析,从而获取到此java文件的相关信息: 在java文件中所存在的东西很多,很复杂,难以用相关的正则表达式去一一匹配.但是,eclip ...

  9. [收藏] Java源码阅读的真实体会

    收藏自http://www.iteye.com/topic/1113732 刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我 ...

随机推荐

  1. epoll事件模型

    事件模型 EPOLL事件有两种模型: Edge Triggered (ET) 边缘触发只有数据到来才触发,不管缓存区中是否还有数据. Level Triggered (LT) 水平触发只要有数据都会触 ...

  2. F 阎小罗的Minimax (第十届山东理工大学ACM网络编程擂台赛 正式赛 )

    题解:by Mercury_Lc 阎小罗的矩阵给的n和m都不超过300,枚举一下所有情况就可以了,用前缀和来储存.数组a[x][y]代表前x行前y列的和是多少,那么枚举每一种切割的方式就可以.注意一下 ...

  3. 下载安装tomcat 部署本地项目

    原文地址:https://blog.csdn.net/weixin_40396459/article/details/81706543 下载地址:http://tomcat.apache.org 点击 ...

  4. sql 查出相同的记录 并把相同记录 显示在一起

    select c.workunit unitname,a.positionid,a.positiontype,a.isfirst,a.mastersort,a.directoraudit, c.wri ...

  5. Java常用工具类之数据库操作辅助类DBUtil.java

    package com.qushida.util; import java.beans.BeanInfo; import java.beans.Introspector; import java.be ...

  6. ZR#988

    ZR#988 解法: 先算出横着能排多少座位, 以及需要排几列, 才能把 n 个座位全部排下来.要使得尽量多的位置在走廊边上, 于是在 n 列中插入走廊的策略是显然的, 我们只要以两列为单位, 在其中 ...

  7. pimpleFoam求解器 vs simpleFoam求解器 vs pisoFoam求解器 vs icoFoam

    翻译自:CFD-online 帖子地址:http://www.cfd-online.com/Forums/openfoam-solving/68072-pimplefoam-vs-simplefoam ...

  8. 2018-2019 20175234 实验三《敏捷开发与XP实践》实验报告

    目录 2018-2019 20175234 实验三<敏捷开发与XP实践>实验报告 实验内容 实验中的问题 码云链接 参考资料 2018-2019 20175234 实验三<敏捷开发与 ...

  9. SCHED_FIFO与SCHED_OTHER调度机制

    疑问 两个线程分别有不同的调度策略,一个SCHED_FIFO,一个SCHED_OTHER,按照之前的理解,SCHED_FIFO实时线程一定会占用CPU一直运行,导致SCHED_OTHER的普通线程得不 ...

  10. zabbix 定义触发器,并使用邮件,微信消息报警。

    触发器可根据监控项获取到的值来进行一些操作,如监控项获取到的values为0,触发器可判断为正常,如果获取到了1,就触发报警. 定义报警方式比较简单,但是用shell脚本实现起来,总是有格式问题,所以 ...