Java :在 ConcurrentHashMap 中,如果更改键,为什么会有不同的输出
Java : In ConcurrentHashMap , why is having differnet output if i changes the key
第一次迭代:-
class ConcurrentHashMapBehaviour
{
public static void main(String[] args)
{
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();
map.put("ONE", 1);
map.put("TWO", 2);
map.put("THREE", 3);
map.put("FOUR", 4);
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()){
String key = (String) it.next();
System.out.println(key+" : "+map.get(key));
map.put("SEVEN", 7);
}
}
}
输出为:
ONE : 1
FOUR : 4
TWO : 2
THREE : 3
SEVEN : 7
更改密钥后的第二次迭代
class ConcurrentHashMapBehaviour
{
public static void main(String[] args)
{
ConcurrentHashMap<String, Integer> map = new
ConcurrentHashMap<String, Integer>();
map.put("ONE", 1);
map.put("TWO", 2);
map.put("THREE", 3);
map.put("FOUR", 4);
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()){
String key = (String) it.next();
System.out.println(key+" : "+map.get(key));
map.put("FIVE", 5);
}
}
}
输出为:
ONE : 1
FOUR : 4
TWO : 2
THREE : 3
所以我的问题是,为什么第一次迭代将 7 个作为输出,而在第二次迭代中不包括 5 个?
Javadoc(我强调):
Similarly, Iterators, Spliterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration.
换句话说,对于迭代器可用的视图没有任何保证。在创建 Iterator
之后,它可能知道也可能不知道地图的更改。唯一的保证是
They do not throw ConcurrentModificationException.
当您键入时
Iterator<String> it = map.keySet().iterator();
while (it.hasNext())
{
String key = it.next();
System.out.println(key + " : " + map.get(key));
map.put("FIVE", 5);
}
您可能会在每次打印值时将 ("FIVE", 5)
放入地图,但这不会将其添加到 运行 迭代器。迭代器不更新。事实上,在没有迭代器的情况下更改迭代列表或映射(例如使用 for each-loop)将导致 ConcurrentModificationException
.
当您在第一个循环之后执行第二个循环并创建一个新的迭代器时。它还将打印出新值:
Iterator<String> it2 = map.keySet().iterator();
while (it2.hasNext())
{
String key = it2.next();
System.out.println(key + " : " + map.get(key));
}
输出:
FIVE : 5
ONE : 1
FOUR : 4
TWO : 2
THREE : 3
第一次迭代:-
class ConcurrentHashMapBehaviour
{
public static void main(String[] args)
{
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();
map.put("ONE", 1);
map.put("TWO", 2);
map.put("THREE", 3);
map.put("FOUR", 4);
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()){
String key = (String) it.next();
System.out.println(key+" : "+map.get(key));
map.put("SEVEN", 7);
}
}
}
输出为:
ONE : 1
FOUR : 4
TWO : 2
THREE : 3
SEVEN : 7
更改密钥后的第二次迭代
class ConcurrentHashMapBehaviour
{
public static void main(String[] args)
{
ConcurrentHashMap<String, Integer> map = new
ConcurrentHashMap<String, Integer>();
map.put("ONE", 1);
map.put("TWO", 2);
map.put("THREE", 3);
map.put("FOUR", 4);
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()){
String key = (String) it.next();
System.out.println(key+" : "+map.get(key));
map.put("FIVE", 5);
}
}
}
输出为:
ONE : 1
FOUR : 4
TWO : 2
THREE : 3
所以我的问题是,为什么第一次迭代将 7 个作为输出,而在第二次迭代中不包括 5 个?
Javadoc(我强调):
Similarly, Iterators, Spliterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration.
换句话说,对于迭代器可用的视图没有任何保证。在创建 Iterator
之后,它可能知道也可能不知道地图的更改。唯一的保证是
They do not throw ConcurrentModificationException.
当您键入时
Iterator<String> it = map.keySet().iterator();
while (it.hasNext())
{
String key = it.next();
System.out.println(key + " : " + map.get(key));
map.put("FIVE", 5);
}
您可能会在每次打印值时将 ("FIVE", 5)
放入地图,但这不会将其添加到 运行 迭代器。迭代器不更新。事实上,在没有迭代器的情况下更改迭代列表或映射(例如使用 for each-loop)将导致 ConcurrentModificationException
.
当您在第一个循环之后执行第二个循环并创建一个新的迭代器时。它还将打印出新值:
Iterator<String> it2 = map.keySet().iterator();
while (it2.hasNext())
{
String key = it2.next();
System.out.println(key + " : " + map.get(key));
}
输出:
FIVE : 5
ONE : 1
FOUR : 4
TWO : 2
THREE : 3