Java ListIterator 与 Iterator 异同
一、概述
基于 fail-fast 机制,我们知道对于ArrayList等集合在迭代过程中是不可进行结构修改操作的,唯一能使用的结构修改操作只有Iterator接口中的remove()方法。
而java.util.ListIterator接口继承自Iterator接口,是专用于列表集合的迭代器,在 Iterator 的基础上,额外提供了 previous、nextIndex、add、set 等方法。
next、previous语义上的小问题
- 迭代器中的
next()方法不应该理解为返回下一个元素,而是返回当前元素,并将指针移向下一个。 cursor永远指向下一个待返回的元素下标。previous()则是将指针向前移动一个位置后返回元素。
比如以下情况:
// 对于 List{3,4,5}
ListIterator<Integer> listIterator = list.listIterator();
boolean isDo = false; //isDo保证只向前移动一次,否则会死循环
while(listIterator.hasNext()){
Integer i = listIterator.next();
if(i.equals(4)&&!isDo){
i = listIterator.previous();
isDo = true;
}
System.out.println(i);
}
最后输出:
3
4 //因为equal(4)时指针已经指向5了, previous会导致指针重回4
//(而不是字面上想的当==4时,返回上一个3)
4
5
修改对迭代过程是否可见?
是否可见具体看类(暂未找到对比)。如 对于ArrayList来说,迭代器并未使用副本数组,因此修改是可见的(但需要一定操作,因为add方法添加元素后会把指针再往后移一位【即,若一直next的话,等于忽略了迭代过程中添加的元素】)
二、一些类对LisIterator实现详解
2.1 ArrayList 对 ListIterator 的实现
对于ArrayList对ListIterator的实现来说,并不是取消了fail-fast机制,而是调用迭代器来修改的话,每次修改后都令expectedModCount = modCount,因此不会报ConcurrentModificationException异常。
源码如下:ListItr是ArrayList的内部类
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index; //构建是可指定迭代开始下标,默认是0
}
public boolean hasPrevious() { return cursor != 0; }
/** 因为cursor始终指向下个元素下标 */
public int nextIndex() { return cursor; }
public int previousIndex() { return cursor - 1; }
/** 返回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]; //lastRet始终保存上次获取元素的下标
}
/** 省略set源码,set方法用以设置lastRet元素 */
/** 添加方法*/
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e); //将元素添加在当前元素后面,也就是cursor的位置
cursor = i + 1; //再将cursor+1,等于忽略刚添加的元素
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
2.2 CopyOnWriteArrayList 对ListIterator的实现
对于CopyOnWriteArrayList,虽然有lisIterator方法,但实则不支持列表迭代器的结构修改方法,如add、remove等(直接抛UnsupportedOperationException),因为它 fail-safe机制本身就支持迭代过程中去修改集合。但修改是不可见的,具体参考CopyOnWriteArrayList对fail-safe实现
Java ListIterator 与 Iterator 异同的更多相关文章
- JAVA中ListIterator和Iterator详解与辨析
在使用Java集 合的时候,都需要使用Iterator.但是java集合中还有一个迭代器ListIterator,在使用List.ArrayList. LinkedList和Vector的时候可以使用 ...
- Java学习之Iterator(迭代器)的一般用法 (转)
迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为"轻量级"对象,因为创建它的代价 ...
- 【转】Java学习之Iterator(迭代器)的一般用法 (转)
[转]Java学习之Iterator(迭代器)的一般用法 (转) 迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭 ...
- Java学习之Iterator(迭代器)的一般用法
迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为“轻量级”对象,因为创建它的代价小. Java中的I ...
- Java集合迭代器 Iterator分析
简介 迭代器是遍历容器的一种常用方法,它屏蔽了容器的实现细节,无需暴露数据结构内部,就可以对容器进行遍历,迭代器本身也是一种设计模式,迭代是一种特殊的遍历方式. Iterator 在java中,迭代器 ...
- Java学习之Iterator(迭代器)
迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为“轻量级”对象,因为创建它的代价小. Java中的I ...
- LinkedList方法总结 ListIterator和Iterator的区别
LinkedList也像ArrayList一样实现了基本的接口,但是它执行某些从操作时比ArrayList更高效,但在随机访问方面要逊色一些.LinkedList中有一些方法虽然名字不同,但可以完成相 ...
- java中的Iterator接口
Iterator接口 Iterator接口也是Java集合框架的成员,但它与Collection系列.Map系列的集合不一样:Collection系列集合.Map系列集合主要用于盛装其他对象,而Ite ...
- atitit.session的原理以及设计 java php实现的异同
atitit.session的原理以及设计 java php实现的异同 1. session的保存:java在内存中,php脚本因为不能常驻内存,所以在文件中 1 2. php的session机制 1 ...
随机推荐
- 歌乐第二弹:C++九九八十一
第一弹传送门:极乐净土 二话不说,上代码(注意事项在第一弹里): #include <windows.h> //q前缀为低音,g为高音,s前缀为半音阶 const int q1 = 131 ...
- shell脚本,文件里面的英文大小写替换方法。
[root@localhost wyb]# cat daxiaoxie qweBNMacb eeeDFSmkl svdIOPtyu [root@localhost wyb]# cat daxiaoxi ...
- windows下使用gcc完成头文件和目标文件编译
环境要求 安装了gcc win+r然后输入cmd , dos界面输入 gcc -v 查看有没有安装gcc 进入正题 新建 text.c文件键入如下代码: #include <stdio.h> ...
- 【dp 状态压缩 单调栈】bzoj3591: 最长上升子序列
奇妙的单调栈状压dp Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个 ...
- 006 CSS三种引入方式
CSS三种引入方式 一.三种方式的书写规范 1.行间式 <div style="width: 100px; height: 100px; background-color: red&q ...
- python 学习总结4
数字类型及操作 一.整数类型 (1)python中的整数与数学中的概念是一致的,可以正也可以负,没有取值范围. pow(x,y)函数是计算x的y次幂,想计算多大就多大. (2)在整数类型中有四种进 ...
- (转)TDD的iOS开发初步以及Kiwi使用入门
本文转自“瞄神”博客 TDD的iOS开发初步以及Kiwi使用入门 测试驱动开发(Test Driven Development,以下简称TDD)是保证代码质量的不二法则,也是先进程序开发的共识.App ...
- (转)UIPanGestureRecognizer
UIPanGestureRecognizer是UIGestureRecognizer类的一个扩展类,其扩展类有UITapGestureRecognizer,UIPinchGestureRecogniz ...
- file结构体
struct file结构体定义在include/linux/fs.h中定义.文件结构体代表一个打开的文件,系统中的每个打开的文件在内核空间都有一个关联的 struct file.它由内核在打开文件时 ...
- LeetCode(110) Balanced Binary Tree
题目 Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced bina ...