黑马程序员--07.集合框架--03.【列表List集合的共性方法】【列表迭代器ListIterator】

集合框架--3

      列表List集合的共性方法       列表迭代器ListIterator

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

1.    List接口

1). Collection常用子接口

(1). Collection常用子接口的继承体系


(2). Collection的子接口:List和Set的区别

[1]. List的特点:元素有序可重复

[2]. Set的特点:元素无序不可重复

List中元素可重复的原因】

List中有索引索引不能重复的,但是索引对应的内容可以重复的。因此,List中的元素可以重复

2). List接口特有的操作方法

List特有方法特点

集合框架的API中,只要操作方法的参数是有关于角标的操作,这个方法就一定是List接口特有的方法

(1). 增

[1].增加一个void add(int index, E element);

【特有的add方法返回void不是boolean

[2]. 增加集合boolean addAll(int index,Collection<? extends E> c);

(2). 删

删除一个:E remove(int index);

    【特有的add方法返回Object类的对象 而不是boolean

    【没有特有的removeAll方法】

(3). 查/获取

[1]. 获取指定位置元素

[2]. 获取指定元素位置

[1]的逆过程【String、StringBuffer和StringBuilder都有这个方法】

{1}. 获取元素第一次出现的位置:int indexOf(Objecto);

{2}. 获取元素最后一次出现的位置:intlastIndexOf(Object o);

[3]. 获取指定区间子集:List<E>subList(int fromIndex, int toIndex);

[4]. 获取List关联迭代器对象:Iterator<E>iterator();

[5]. 获取List关联列表迭代器对象:Iterator<E>listIterator();

(4).

Collection中没有元素的修改操作】

修改一个:E set(int index, Eelement);

(5). 集合操作

[1]. 获取子集:List<E>subList(int fromIndex, int toIndex);

【List练习】   

List al =new ArrayList();
al.add("java001");
al.add("java002");
al.add("java003");
sop(al);
 
//指定位置添加元素
al.add(1, "java009");
sop(al);
 
//删除指定位置元素
//al.remove(2);
//sop(al);
 
//修改指定位置的元素
al.set(2, "java007");
sop(al);
 
//遍历查询 ----角标查询法
for(int i=0; i< al.size(); i++)
    sop("al["+i+"] ="+al.get(i));
 
//获取元素的位置
sop("index ="+ al.indexOf("java007"));
 
//取子集合
List subList =al.subList(1, 3);
sop(subList);

打印结果:

2.    列表迭代器ListIterator

1). 问题产生背景

/*需求:对List集合中的元素进行取出,,取出的时候,做一些额外的操作

 *迭代的过程中,准备同时添加元素或者删除元素

 * */

(1). 代码

/

/出问题的方法
public void methodConcurrentModificarionException(){
    Iteratorit = al.iterator();
    sop(al);
    while(it.hasNext()){
        Objectobj =it.next();
        if(obj.equals("java002")){
            al.add("java008");
        }
    }
    sop(al);
}

运行时,抛出异常:


(2). 异常产生的原因

if(obj.equals("java002")){

    al.add("java008");

}

[1]. 原理上 (单线程思想)分析

al存放了元素对象的引用,it也同样存放了对象元素的引用 (通过Iterator it = al.iterator();)。所以,可以通过al来操作集合可以通过it来存取元素。但是在一个线程里面,这样操作可能存在共享数据安全隐患

运行到al.add("java008");之前,迭代器引用it仅仅知道容器al原来有6个元素:[java001, java002, java003, java004, java005,java006]。这时候al添加了新的元素(al添加了一个新的元素java008) ,变动了整个集合底层数据结构,而it还是原有数据的引用集合,并不知道新的元素的存在

下次迭代循环的时候,it要不要迭代这个新的元素呢?还是按照以前的元素进行迭代这个时候it本身也不清楚如何处理,此时蹦出了并发访问异常

[2]. 建议的做法

不建议的做法:对同一组数据,使用多个引用进行多种操作

【建议做法】要么使用集合的操作方式要么使用迭代器的操作方式

2). 边迭代,边删除

(1). Iterator的删除方法

【发现】Iterator在对数据进行增删改查的处理中,有一个删除的方法:

void remove(); 通过集合关联的Iterator对象本身,可以删除集合中的数据。

【注意】这个方法不接受任何参数

示例代码如下:

//边迭代。边删除
    public void methodIterationAndRemove(){
        Iteratorit = al.iterator();
        sop(al);
        while(it.hasNext()){
            Objectobj =it.next();
            if(obj.equals("java002"))
                it.remove();
            sop("obj ="+ obj);
        }
        sop(al);
    }


问题1】这段程序发生并发异常么?

不会!!因为在迭代元素的时候,是通过it本身的方法remove进行元素的删除的,而不是通过al的remove方法进行删除的。所以,不会发生并发异常。

问题2】已知:al中的数据有[java001,java002, java003, java004, java005, java006], 当while中的if条件成立的时候,java002这个元素被删除掉。那么进行到sop("obj ="+ obj);的时候,会有打印值么?为什么?

会有打印值,打印出来的仍然是java002。

原因就是:集合中存储的元素的引用不是对象元素本身。所以it通过自身的remove方法删除的仅仅是java002这个字符串的引用。但是,在删除之前,语句Object obj=it.next();已经保证java002这个字符串被String类型的引用obj所指向,所以打印的时候,是可以看到java002被打印出来。

运行结果:


【能够边迭代,边添加呢?】iterator类本身没有这样的方法,所以不能通过Iterator这个类来实现。这时候,Java提供了一个叫做ListIteratorIterator子类来完成这样的操作。

3). ListIterator的使用

(1). ListIterator的概述

[1]. public interfaceListIterator<E> extends Iterator<E>

ListIterator是Iterator接口的子接口。

[2]. Iterator接口的局限性

仅仅有判断【hashNext()获取【next()删除【remove()这三个功能。如果想进行其他操作,就要使用Iterator的子接口ListIterator

[3].ListIterator同样具备C、R、U和D

只有List的实例才能获取ListIterator这个类的对象别的容器实例没有

(2). 通过ListIterator实现边迭代,边添加

//采用ListIterator进行迭代期间的CRUD
    public void methodUsingListIterator(){
        ListIterator it = al.listIterator();
        sop(al);
        while(it.hasNext()){
            Object obj =it.next();
            if(obj.equals("java002")){
                it.add("java008");
            }
        }
        sop(al);
    }

运行不会发生异常。

打印结果:

[java001, java002, java003, java004, java005,java006]

[java001, java002, java008, java003, java004,java005, java006]

(3). ListIterator的其他功能

[1]. 与Iterator中hasNext()相对应的方法:hasPrevious()

举例:逆向遍历列表

//双向遍历
    public void methodDoubleDirecIteration(){
        ListIteratorit = al.listIterator();
        sop("正向迭代...");
        sop(al);
        while(it.hasNext()){
            sop(it.next());
        }
        sop("*************************************");
        while(it.hasPrevious()){
            sop(it.previous());
        }
    }

打印结果:


 

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值