Java  集合5  ListIterator

需求:如果集合中存在 "itcast" 则插入 “java”
代码:

package Collection;
import  java.util.*;
/*
需求:根据上一个ListDemo 的练习,提出新的需求。
当集合中存在“itcast” 时,向集合中加入 “Java”
 */
public class ListIteratorDemo {
    public static void main(String[] args){
        //1,创建 List 集合
        List list = new ArrayList();

        //2.向集合中添加元素
        list.add("itcast1");
        list.add("itcast");
        list.add("itcast1");
        list.add("itcast1");

        //要获取集合中的元素 获取迭代器对象
        Iterator it = list.iterator();
        while(it.hasNext()){
            if("itcast".equals(it.next())){
                list.add(1,"java");
            }
        }
        System.out.println(list);
    }
}

但是,这样运行之后报一个运行错误: ConcurrentModificationException
查找API 找到异常:
不允许这样的修改时,可以通过检测到对象的并发修改的方法来抛出此异常。
例如,一个线程通常不允许修改集合,而另一个线程正在遍历它。 一般来说,在这种情况下,迭代的结果是未定义的。

其实就是:当在迭代时,不允许对他进行修改/
—————————————————————具体的原因分析————————————————–

迭代器获取元素的原理:从开头获取时,光标在第一个元素之前,先判断是否有下一个,在进行获取,获取了最后一个元素后,光标在最后一个元素之后,此时再判断是否有下一个元素,没有。结束获取。(n 个元素 使用迭代器时,有n+1 个光标位置)
在我们通过集合对象获取迭代器对象时:集合对象.iterator(); 迭代器知道集合中的元素个数。

当我们在获取元素是找到在集合中存在”itcast” 并且通过集合的添加方式 add() 添加时,我们就改变了集合,但是迭代器是不知道集合的变化的,继续迭代,数据就会出现不确定性,从而导致异常出现

解决的办法:在集合迭代时,不要使用集合的方法去操作数据。

但是如果我们的需求就是要在迭代时操作集合中的数据(增加,删除/修改)————那么我们就使用迭代器的方法,但是Iterator 只有 hasNext()/判断 next()/获取 remove()/删除。继而查看他的子接口

ListIterator
用于允许程序员沿任一方向遍历列表的列表的迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
方法(有父亲接口的所有方法)
void add(E e) 将指定的元素插入列表(可选操作)。
boolean hasNext() 返回 true如果遍历正向列表,列表迭代器有多个元素。
E next() 返回列表中的下一个元素,并且前进光标位置。
void remove() 从列表中删除由 next()或 previous()返回的最后一个元素//父亲接口具备的方法
int nextIndex() 返回随后调用 next()返回的元素的索引。//正向
//反向
boolean hasPrevious() 返回 true如果遍历反向列表,列表迭代器有多个元素。/
E previous() 返回列表中的上一个元素,并向后移动光标位置。
int previousIndex() 返回由后续调用 previous()返回的元素的索引。
void set(E e) 用 指定的元素替换由 next()或 previous()返回的最后一个元素

如何让获取 列表迭代器的对象:在Collection 中有一个方法 listIterator() 返回的是列表迭代器对象//listIterator(int index) 从集合中的指定位置返回列表迭代器

修改后的代码:

package Collection;
import  java.util.*;
/*
需求:根据上一个ListDemo 的练习,提出新的需求。
当集合中存在“itcast” 时,向集合中加入 “Java”
 */
public class ListIteratorDemo {
    public static void main(String[] args){
        //1,创建 List 集合
        List list = new ArrayList();

        //2.向集合中添加元素
        list.add("itcast1");
        list.add("itcast");
        list.add("itcast1");
        list.add("itcast1");

        //要获取集合中的元素 获取迭代器对象。列表迭代器通过 List的方法获取
        ListIterator it = list.listIterator();//使用列表迭代器******
        while(it.hasNext()){
            if("itcast".equals(it.next())){
               // list.add(1,"java");
                it.add("java");
            }
        }
        System.out.println(list);
    }
}

//列表迭代器只有List 接口有。而且这个迭代器还可以在迭代中完成增删改查,同时这个迭代器还可以反向遍历,主要是因为List 集合中有索引。
注意:
列表迭代器的获取方法(listIterator())定义在Collection 中,List 继承了 Collection 但是列表迭代器只能由 List 的对象获取,不能由Collection 的对象获取?
因为 列表迭代器是对列表进行操作List 是一个带索引的列表,所以只能通过 List来 获取列表迭代器的对象

猜你喜欢

转载自blog.csdn.net/Stitch__/article/details/82355270
今日推荐