列表迭代器
<3>ListIterator(列表迭代器)
List集合特有的迭代器
接口完整定义
public interface ListIterator<E>extends Iterator<E>
JDK API说明
系列表迭代器,允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置。
演示一个使用
package java_practice;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ListDemo {
public static void main(String args[]) {
List<String> list = new ArrayList<String>();
list.add("Hello");
list.add("world");
list.add("java");
Iterator<String> it = list.iterator();
// while(it.hasNext()) {
// String s = it.next();
// if(s.equals("world"))
// {
// list.add("javaee");
// }
//
//}
//
ListIterator<String> lit = list.listIterator();
while(lit.hasNext())
{
String s = lit.next();
if(s.equals("world"))
{
lit.add("javaee");
}
}
System.out.println(list);
}
}
一个疑问就是为什么ListIterator没有报异常?
我们还是追溯源码,最终整理如下
public interface List<E>{
Iterator<E> iterator();
ListIterator<E> listIterator();
boolean add(E e)
}
public abstract class AbstractList<E>
{
protected transient int modCount = 0;
}
public class ArrayList<E> extends AbstractList<E>implements List<E>
{
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!//每次调用add()会使modCount++
elementData[size++] = e;
return true;
}
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
public ListIterator<E> listIterator() {
return new ListItr(0);
}
}
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
追诉到根本就是ListItr的add()方法。通过源码分析可以了解到,这里的add()方法在使用后会给预期的变量重新赋值,所以会使预期和实际的统一,这样就不会报异常了。
<4>增强for循环
还是从JDK API查找资料从Collection出发
public interface Collection<E>extends Iterable<E>
追溯Iterable,有理可依。
public interface Iterable<T>实现这个接口允许对象成为 "foreach" 语句的目标。
并且Iterable给出了其可使用的迭代器
Iterator<T> iterator()
返回一个在一组 T 类型的元素上进行迭代的迭代器。
所以可以了解到增强for循环,简化数组和Collection集合的遍历。实现Iterable的类允许其对象成为增强型for循环语句的目标。版本在JDK5之后,内部实现原理是Iterator迭代器。
使用格式如下:
举例示范
int[] arr = {1,2,3,4,5};
for(int i:arr)
{
System.out.println(i);
}
List<String> list = new ArrayList<String>();
list.add("Hello");
list.add("world");
list.add("java");
for(String s :list)
{
System.out.println(s);
}
验证内部实现原理
如何验证内部实现原理是Iterator迭代器,通过Iterator迭代器迭代添加过程中的并发修改异常的特点来验证
List<String> list = new ArrayList<String>();
list.add("Hello");
list.add("world");
list.add("java");
for(String s :list)
{
if(s.equals("java")){
list.add("javaee");
}
System.out.println(s);
}
异常信息摘录:
Exception in thread “main” java.util.ConcurrentModificationException
at java.util.ArrayList Itr.next(ArrayList.java:857)
at java_practice.ListDemo.main(ListDemo.java:15)
这里的异常和并发修改的异常一样,所以可以验证出内部实现原理是Iterator迭代器。也可以通过异常追溯源码来验证。
- 点赞
- 收藏
- 关注作者
评论(0)