java hashmap 迭代器_Java ConcurrentHashMap示例和迭代器

如果是Java开发者,那么必须知道在使用迭代器完成其所有元素时要修改Collection对象时出现会出现ConcurrentModificationException异常。 实际上Java Collection Framework迭代器是迭代器设计模式实现的很好的例子。

Java ConcurrentHashMap

Java 1.5引入了带有Collection类实现的java.util.concurrent包,允许在运行时修改集合对象。

ConcurrentHashMap示例

ConcurrentHashMap类是一个类似于HashMap的类,但在尝试在运行时修改映射时工作正常。

下面来运行一个示例程序来了解和熟悉,文件:ConcurrentHashMapExample.java -

package com.yiibai.util;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample {

public static void main(String[] args) {

//ConcurrentHashMap

Map myMap = new ConcurrentHashMap();

myMap.put("1" "1");

myMap.put("2" "1");

myMap.put("3" "1");

myMap.put("4" "1");

myMap.put("5" "1");

myMap.put("6" "1");

System.out.println("ConcurrentHashMap before iterator: "+myMap);

Iterator it = myMap.keySet().iterator();

while(it.hasNext()){

String key = it.next();

if(key.equals("3")) myMap.put(key+"new" "new3");

}

System.out.println("ConcurrentHashMap after iterator: "+myMap);

//HashMap

myMap = new HashMap();

myMap.put("1" "1");

myMap.put("2" "1");

myMap.put("3" "1");

myMap.put("4" "1");

myMap.put("5" "1");

myMap.put("6" "1");

System.out.println("HashMap before iterator: "+myMap);

Iterator it1 = myMap.keySet().iterator();

while(it1.hasNext()){

String key = it1.next();

if(key.equals("3")) myMap.put(key+"new" "new3");

}

System.out.println("HashMap after iterator: "+myMap);

}

}

当尝试运行上面的代码时,输出结果如下:

ConcurrentHashMap before iterator: {1=1 5=1 6=1 3=1 4=1 2=1}

ConcurrentHashMap after iterator: {1=1 3new=new3 5=1 6=1 3=1 4=1 2=1}

HashMap before iterator: {3=1 2=1 1=1 6=1 5=1 4=1}

Exception in thread "main" java.util.ConcurrentModificationException

at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)

at java.util.HashMap$KeyIterator.next(HashMap.java:828)

at com.test.ConcurrentHashMapExample.main(ConcurrentHashMapExample.java:44)

查看输出,ConcurrentHashMap负责处理映射中的任何新条目,而HashMap抛出ConcurrentModificationException异常。

如果仔细看看异常堆栈跟踪,抛出Exception的语句是:

String key = it1.next();

这意味着新条目已插入HashMap,但Iterator执行失败。 实际上,Collection对象上的Iterator是快速的,即结构中的任何修改或集合对象中的条目数都将触发Iterator抛出的此异常。

那么Iterator如何知道HashMap中有一些修改。 从HashMap中获取了一组键,然后迭代它。

HashMap包含一个用于计算修改次数的变量,Iterator在调用next()函数以获取下一个条目时使用它。

文件:HashMap.java -

/**

* The number of times this HashMap has been structurally modified

* Structural modifications are those that change the number of mappings in

* the HashMap or otherwise modify its internal structure (e.g.

* rehash). This field is used to make iterators on Collection-views of

* the HashMap fail-fast. (See ConcurrentModificationException).

*/

transient volatile int modCount;

现在要证明上述观点,在插入新条目时稍微更改代码以从迭代器循环中出来。需要做的就是在put调用之后添加一个break语句。

if(key.equals("3")){

myMap.put(key+"new" "new3");

break;

}

现在执行修改后的代码,输出将是:

ConcurrentHashMap before iterator: {1=1 5=1 6=1 3=1 4=1 2=1}

ConcurrentHashMap after iterator: {1=1 3new=new3 5=1 6=1 3=1 4=1 2=1}

HashMap before iterator: {3=1 2=1 1=1 6=1 5=1 4=1}

HashMap after iterator: {3=1 2=1 1=1 3new=new3 6=1 5=1 4=1}

最后,如果不添加新条目但更新现有键值对会怎样,它也会抛出异常吗?

更改原始程序中的代码,如下所示 -

//myMap.put(key+"new" "new3");

myMap.put(key "new3");

这次应该没有问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值