Java中List集合的列表迭代器详解(内附一个关于并发修改异常的小案例以及List的一道面试题)
2019-05-11 15:39
507 查看
什么是列表迭代器呢?
列表迭代器:ListIterator listIterator():List集合特有的迭代器。该迭代器继承了Iterator迭代器,所以就可以直接hasNext()和next()方法。
那么,相较于Iterator来说他又有什么特有功能呢?通过查看API,我们可以发现:
- Object previous():获取上一个元素
- boolean hasPrevious():判断是否有元素
我们不难猜出,这个功能可以实现逆向遍历。
但是,我们需要注意:ListIterator可以实现逆向遍历,但是必须先正向遍历,才能逆向遍历,所以一般无意义,不使用。
示例代码如下:
public class ListIteratorDemo { public static void main(String[] args) { //创建集合对象 List list = new ArrayList(); list.add("hello"); list.add("world"); list.add("java"); //ListIterator listIterator():List集合特有的迭代器 ListIterator lit = list.listIterator();//子类对象 /* while(lit.hasNext()) { String s = (String) lit.next(); System.out.println(s); }*/ // System.out.println("-----------"); // System.out.println(lit.previous()); // System.out.println(lit.previous()); // System.out.println(lit.previous()); //NoSuchElementException //System.out.println(lit.previous()); while(lit.hasPrevious()) { String s = (String) lit.previous(); System.out.println(s); } System.out.println("-----------"); //迭代器 Iterator it = list.iterator(); while(it.hasNext()) { String s = (String) it.next(); System.out.println(s); } System.out.println("-------------------"); } }
那么,我现在有一个需求:
我有一个集合,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。
分析:
- A:创建集合对象
- B:添加元素
- C:迭代器遍历
- D:通过迭代器的hasNext方法判断是否有此元素,然后获取元素后加入判断
按照我们所想,代码实现如下:
public class ListIteratorDemo2 { public static void main(String[] args) { //创建list集合对象 List list = new ArrayList(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //迭代器遍历 Iterator it = list.iterator(); //通过迭代器的hasNext方法判断是否有此元素 while(it.hasNext()) { //通过迭代器的next方法获取元素 String s =(String) it.next(); //判断 if("world".equals(s)) { list.add("javaee"); } } } }
但是,我们运行后发现,他是有问题的!他会报:ConcurrentModificationException的错误。
那么,这到底是什么错误呢?又是为什么呢?
通过查看API,我们可以知道:ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常
产生原因:
- 迭代器是依赖于集合而存在的,在判断成功后集合中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。
- 其实这个问题描述的是:迭代器遍历元素的时候,通过集合是不能修改元素的。
那么,如何解决呢?
- A:迭代器迭代元素,迭代器修改元素
元素是跟在刚才迭代的元素后面的。 - B:集合遍历元素,集合修改元素(普通for)
元素在最后添加的。
代码示例如下:
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; public class ListIteratorDemo2 { public static void main(String[] args) { //创建list集合对象 List list = new ArrayList(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //迭代器遍历 Iterator it = list.iterator(); //通过迭代器的hasNext方法判断是否有此元素 /* while(it.hasNext()) { //通过迭代器的next方法获取元素 String s =(String) it.next(); if("world".equals(s)) { list.add("javaee"); } }*/ //方式1:迭代器迭代元素,迭代器修改元素 //而Iterator迭代器却没有添加功能,所以我们使用其子接口ListIterator /* ListIterator lit = list.listIterator(); while(lit.hasNext()) { String s = (String) lit.next(); if("world".equals(s)) { lit.add("javaee"); } }*/ /* //方式2:集合遍历元素,集合修改元素 for(int x = 0;x < list.size();x++) { String s = (String) list.get(x); if("world".equals(s)) { list.add("javaee"); } } System.out.println("list:"+list); } }
List:(面试题List的子类特点)
- ArrayList
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。 - Vector
底层数据结构是数组,查询快,增删慢
线程安全,效率低。 - LinkedList
底层数据结构是链表,查询慢,但是增删快
线程不安全,效率高。
那么, List有三个儿子,我们到底使用谁呢?
看需求(情况)
要安全吗?
- 要
Vector(及时要安全,也不用这个,后面有替代的) - 不要
ArrayList或者LinkedList
查询多:ArrayList
增删多:LinkedList
最后,如果你什么都不懂,那就用ArrayList!
相关文章推荐
- Java之集合框架 List接口的特有方法、迭代器的并发修改异常以及LinkedList特有方法
- Java基础知识强化之集合框架笔记19:List集合迭代器使用之 并发修改异常的产生原因 以及 解决方案
- Java集合迭代器之fail-fast机制: 关于java集合的遍历以及ConcurrentModificationException(并发操作异常)
- 关于Java的散列桶, 以及附上一个案例-重写map集合
- 关于java集合的遍历以及ConcurrentModificationException(并发操作异常)
- Java Iterator ListIterator 迭代器 以及 并发修改异常 ConcurrentModificationException
- 集合学习总结2-List - --迭代器遍历的时候不能添加,会爆并发修改异常
- Java学习篇之迭代器并发修改异常问题
- Java集合之ArrayList和LinkedList的实现原理以及Iterator详解
- 关于Hibernate中fatch=eager的bag集合(一个java List)使用Criteria查询出现重复记录的问题
- java中的集合,迭代器的使用以及java中的异常
- java里面在遍历集合的时候对集合进行添加或者删除修改时的并发修改异常
- 阿里巴巴 Java 开发手册:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法
- java并发实战第六章(2)非阻塞式线程安全列表与一般List集合多线程情况下的比较
- linkedlist中使用迭代器出现并发修改异常,ConcurrentModificationException异常
- 由一道Java面试题想到的(关于类初始化以及多态)(一)
- List集合遍历时修改元素出现并发修改异常总结
- Java集合之ArrayList和LinkedList的实现原理以及Iterator详解
- java面试题15--迭代器并发修改异常ConcurrentModificationException
- 关于集合中在迭代器中用集合的对象删除元素的并发异常问题