设计模式之——迭代器模式

迭代器是一个对象,提供了一种可以遍历聚合对象(存储数据的数据集或容器)的一种方式,开发人员在利用迭代器获取数据元素的过程中,不必了解容器的底层实现,同时,也不会暴露对象的内部细节方法。
1、关于容器的使用主要有3个方面:
(1) 使用容器的iterator()方法返回的是一个迭代器Iterator,通过Iterator的next()方法返回下一个元素
(2) 使用Iterator的hasNext()方法,判断容器中是否还有元素,如果有,则通过next()方法获取
(3) 通过remove()方法删除容器中返回的元素,不是在容器中直接删除容器中的元素
使用Iterator获取list中的元素:
IteratorList.java

import java.util.ArrayList;
import java.util.Iterator;

public class IteratorList {
    public static void main(String[] args){
        ArrayList al = new ArrayList();
        al.add( "a" );
        al.add( "b" );
        al.add( "c" );
        Iterator it = al.iterator();
        while (it.hasNext()){
            System.out.print( it.next()+"\t" );
        }
    }
}

输出:

a	b	c

在List中也存在Iterator的派生成员,ListIterator
Iterator与ListIterator的区别:
Iterator只能正向遍历集合,适合获取移动元素。
ListIterator继承自Iterator,专门针对List,可以从两个方向来遍历List,同时支持元素的修改。
使用Iterator获取Map中的key,value值:
IteratorMap.java

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class IteratorMap {
    public static void main(String[] args){
        HashMap<String,Integer> map = new HashMap<String,Integer>(  );
        map.put( "aa", 9);
        map.put( "bb",10 );
        map.put( "cc",11 );
        Iterator it = map.entrySet().iterator();
        while (it.hasNext()){
            Map.Entry<String,Integer> entry = (Map.Entry) it.next();
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println( key + "\t" + value );
        }
    }
}

输出:

aa	9
bb	10
cc	11

在Map中,使用Iterator,先将Map中的对象放在set集合中,再使用迭代器获取
2、iterator()方法常见的异常——ConcurrentModificationException异常
ConcurrentModificationException异常,通常是在遍历容器的同时又对容器增删元素,或者是多线程造成的。即,当一个线程使用迭代器在遍历容器的元素时,另一个线程对容器进行增删操作。
IteratorException.java

import java.util.ArrayList;
import java.util.Iterator;

public class IteratorException {
    public static void main(String[] args){
        ArrayList al = new ArrayList();
        al.add( "a" );
        al.add( "b" );
        al.add( "c" );
        al.add( "e" );
        Iterator it = al.iterator();
        while (it.hasNext()){
            Object obj = it.next();
            System.out.println( obj );
            if (obj.equals( "c" )){
                al.add( "d" );
            }
        }
    }
}

异常输出:

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at IteratorException.main(IteratorException.java:13)
a	
b	
c 

原因:
当调用容器的iterator()方法返回Iterator对象时,把容器中包含的对象的个数赋值给了变量expectedModCount,在调用next()方法时,expectedModCount变量会与实际的对象个数modCount进行比较,若不相等,则抛出ConcurrentModificationException异常。
a. 单线程解决方法:
<1> 在遍历的过程中将对象存放在一个集合中,遍历结束后,调用removeAll()方法删除;
<2>使用it.remove()方法删除
b. 多线程抛出ConcurrentModificationException异常:
<1>JDK1.5引入了线程安全容器,如ConcurrentHashMap和CopyOnWriteArrayList等,可以使用线程安全的容器,来代替非线程安全的容器
<2>使用迭代器遍历容器时,可以放在synchronized代码块中,但会严重影响程序的性能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值