java.util.ArrayList学习笔记(二)
来源:互联网 发布:剑桥少儿英语网络课程 编辑:程序博客网 时间:2024/05/16 11:21
本文接java.util.ArrayList学习笔记(一)
public ListIterator<E> listIterator(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index);}
获取由指定位置开始的列表迭代器。即,用户第一次调用迭代器的next()
方法返回的是列表中下标为index
的元素。但是迭代器的调用方仍然可以使用本迭代器进行列表中元素的遍历。在这里需要特别注意列表迭代器游标的有效位置为:0 ~ size。当 index = size时,则代表列表迭代器的初始游标在列表的末尾,其next()方法将返回null或者抛出异常,一般可以用于逆向遍历列表。
public ListIterator<E> listIterator()
返回一个从列表头部开始的列表迭代器,其内部实现采用的是:listIterator(0)
。
public Iterator<E> iterator()
返回一个从列表头部开始的基本迭代器。
public List<E> subList(int fromIndex, int toIndex)
返回当前列表的一个子列表。其中元素共享,即:在子列表中发生的修改会直接反映到初始列表中,反之亦然。
私有内部类
基础迭代器(Itr)
参数介绍
int cursor
迭代器当前的游标。迭代器的游标代表的为:当调用next()
方法时,返回的列表元素的下标。
int lastRet = -1
最后一次调用next()方法返回的元素的下标。默认为-1。
int expectedModCount = modCount
迭代器创建时,列表对象瞬态的可能的结构变化次数,主要用于检测是否存在并发修改,从而导致并发错误。
方法介绍
public boolean hasNext()
判断当前迭代器调用next()方法是否还有有效元素返回。当列表的游标已经达到列表末尾时,即:cursor == size时候,则返回false,否则返回true。
public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i];}
返回当前迭代器正向遍历的下一个元素。注意,本算法中有两次并发结构修改检测,分别是,强校验:方法开始时,调用checkForComodification进行结构性修改次数检测;弱校验:如果当前游标的位置高于列表的容量,产生情形为:列表发生元素的删除操作,并调用了trimToSize来降低列表的空间占用。在成功完成校验后,需要交迭代器游标后移,并将最后一次访问的元素的坐标设定为访问元素的下标。
public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); }}
删除列表迭代器刚刚访问的元素。当迭代器并没有访问任何元素,或者刚刚访问的元素已经被删除时,其内部基于ArrayList.this.remove()
实现。在完成删除后,需要将迭代器游标前移,将最后一次访问元素的下标置为-1,并对迭代器中结构性修改次数进行更新。
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
检测除持有本迭代器的线程外,是否有潜在的并发修改冲突。其基本原理是检测列表对象的
列表迭代器(ListItr)
继承结构
方法介绍
具体方法说明,请参见:java.util.ListIterator学习笔记。
其内部基本基于ArrayList中的方法实现。在进行元素访问操作时,均会进行同步修改校验。
子列表(SubList)
构造方法
SubList(AbstractList<E> parent, int offset, int fromIndex, int toIndex) { this.parent = parent; this.parentOffset = fromIndex; this.offset = offset + fromIndex; this.size = toIndex - fromIndex; this.modCount = ArrayList.this.modCount;}
由构造方法,我们可以看出:子列表持有的并不是父亲列表中元素的复制,而是直接维持一个父亲列表的引用,因此子列表对其中元素的修改会直接影响到父亲列表,甚至是根列表,反之亦然。并且,子列表的结构修改次数是与根列表的相同,用于检测并发的修改冲突。
基本属性
private final AbstractList<E> parent;
代表当前子列表的直接父亲列表。即:列表3是列表2的子列表,列表2为列表1的子列表,则在列表3中,parent指向的是列表2。
private final int parentOffset;
当前子列表相对于直接父亲列表的元素偏移量。即:列表3相对于列表2的元素偏移量。
private final int offset;
当前子列表相对于根列表的元素偏移量,即:列表3相对于列表1的元素偏移量。
int size;
当前子列表的长度。
注:对于子列表的接口说明,可以参见java.util.AbstractList学习笔记。在ArrayList的实现中,通过数组的下标和数组的copyOf函数实现subList的所有功能。其实现的逻辑与ArrayList本身的实现逻辑大体相同,在此不做赘述。
- java.util.ArrayList学习笔记(二)
- java.util.ArrayList学习笔记(一)
- java.util.ArrayList学习
- java.util包学习笔记二
- java.util包学习笔记二
- Java ArrayList学习笔记
- java.util.ArrayList
- JAVA.Util.ArrayList
- java.util.ArrayList size()
- 【源代码】java.util.ArrayList
- 11 java.util.ArrayList
- java.util.ArrayList 源码
- Java-Util之ArrayList
- java.util.ArrayList<E>
- java.util.ArrayList
- java.util.ArrayList
- java.util.ArrayList
- 自己理解的java.util.ArrayList(二)实现类
- Class.forName()用法详解
- 编写函数int stat(int a[],int n,int c[][2])。
- win7X64位安装mysql-5.7.16
- 返回json的日期格式问题
- React--引用(refs and the DOM)
- java.util.ArrayList学习笔记(二)
- 论#coding=utf-8的位置
- 有时候,eclipse中用tomcat运行的时候,很容易出现,运行出错。但是代码没错,这时候要检查下运行的时间
- 缓存activity的方法:.onSaveInstanceState和onRestoreInstanceState
- Android在广播接收者中弹出对话框
- 一分钟解决Xcode的Undefined symbols for architecture x86_64编译错误
- C# 获取IP地址
- sql解决数据库日志文件过大的问题
- 20. Valid Parentheses