迭代#0中的项目的最佳方法是什么?
像这样迭代#0:
public static void printMap(Map mp) {Iterator it = mp.entrySet().iterator();while (it.hasNext()) {Map.Entry pair = (Map.Entry)it.next();System.out.println(pair.getKey() + " = " + pair.getValue());it.remove(); // avoids a ConcurrentModificationException}}
阅读更多关于#0
如果你只对键感兴趣,你可以遍历map的#0:
Map<String, Object> map = ...; for (String key : map.keySet()) {// ...}
如果您只需要值,请使用#0:
for (Object value : map.values()) {// ...}
最后,如果您同时想要键和值,请使用#0:
for (Map.Entry<String, Object> entry : map.entrySet()) {String key = entry.getKey();Object value = entry.getValue();// ...}
一个警告:如果你想在迭代中删除项目,你需要通过迭代器这样做(参见Karim79的答案)。但是,更改项目值是可以的(参见#0)。
这要看情况而定。如果你知道你将需要每个条目的键和值,那么通过entrySet。如果你只需要值,那么有values()方法。如果你只需要键,那么使用keyset()。
entrySet
values()
keyset()
一个不好的做法是遍历所有的键,然后在循环中,总是做map.get(key)来获取值。如果你这样做,那么我写的第一个选项是给你的。
map.get(key)
你可以通过多种方式迭代#0中的条目。像这样获取每个键和值:
Map<?,?> map = new HashMap<Object, Object>();for(Entry<?, ?> e: map.entrySet()){System.out.println("Key " + e.getKey());System.out.println("Value " + e.getValue());}
或者你可以得到钥匙列表
Collection<?> keys = map.keySet();for(Object key: keys){System.out.println("Key " + key);System.out.println("Value " + map.get(key));}
如果您只想获取所有值并且不关心键,您可以使用:
Collection<?> values = map.values();
更聪明:
for (String key : hashMap.keySet()) {System.out.println("Key: " + key + ", Value: " + map.get(key));}
for (Map.Entry<String, String> item : hashMap.entrySet()) {String key = item.getKey();String value = item.getValue();}
从引用如何在Java中迭代映射中提取:
Java中有几种迭代Map的方法。让我们回顾一下最常见的方法,并回顾它们的优缺点。由于Java中的所有映射都实现了Map接口,因此以下技术适用于任何映射实现(HashMap、TreeMap、LinkedHashMap、Hashtable等)
Map
HashMap
TreeMap
LinkedHashMap
Hashtable
方法#1:使用For-每个循环迭代条目。
这是最常见的方法,在大多数情况下更可取。如果您在循环中同时需要map键和值,则应使用它。
Map<Integer, Integer> map = new HashMap<Integer, Integer>();for (Map.Entry<Integer, Integer> entry : map.entrySet()) {System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());}
请注意,Java5中引入了For-每个循环,因此此方法仅适用于该语言的较新版本。如果您尝试迭代null的map,For-每个循环也会抛出NullPointerException,因此在迭代之前,您应该始终检查null引用。
NullPointerException
方法#2:使用For-每个循环迭代键或值。
如果您只需要映射中的键或值,您可以迭代keySet或值而不是entrySet。
Map<Integer, Integer> map = new HashMap<Integer, Integer>(); // Iterating over keys onlyfor (Integer key : map.keySet()) {System.out.println("Key = " + key);} // Iterating over values onlyfor (Integer value : map.values()) {System.out.println("Value = " + value);}
这种方法比entrySet迭代(大约快10%)提供了轻微的性能优势,并且更干净。
方法#3:使用Iterator进行迭代。
使用泛型:
Map<Integer, Integer> map = new HashMap<Integer, Integer>();Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();while (entries.hasNext()) {Map.Entry<Integer, Integer> entry = entries.next();System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());}
没有泛型:
Map map = new HashMap();Iterator entries = map.entrySet().iterator();while (entries.hasNext()) {Map.Entry entry = (Map.Entry) entries.next();Integer key = (Integer)entry.getKey();Integer value = (Integer)entry.getValue();System.out.println("Key = " + key + ", Value = " + value);}
您还可以使用相同的技术来迭代keySet或值。
keySet
这个方法看起来可能是多余的,但它有自己的优点。首先,它是在旧版本的Java中迭代map的唯一方法。另一个重要的特性是,它是唯一允许你在迭代期间通过调用iterator.remove()从map中删除条目的方法。如果你在For-每个迭代期间尝试这样做,你将得到Javadoc所说的“不可预测的结果”。
iterator.remove()
从性能的角度来看,此方法等于For-每个迭代。
方法#4:遍历键并搜索值(效率低下)。
Map<Integer, Integer> map = new HashMap<Integer, Integer>();for (Integer key : map.keySet()) {Integer value = map.get(key);System.out.println("Key = " + key + ", Value = " + value);}
对于方法#1来说,这可能看起来是一个更干净的替代方案,但在实践中,它非常缓慢和低效,因为通过键获取值可能很耗时(在不同的Map实现中,这种方法比方法#1慢20%-200%)。如果你安装了FindBugs,它会检测到这一点并警告你低效的迭代。应该避免这种方法。
结论:
如果您只需要map中的键或值,请使用方法#2。如果您坚持使用旧版本的Java(少于5)或计划在迭代期间删除条目,则必须使用方法#3。否则使用方法#1。