|
1 |
| -##如何遍历map对象(如HashMap) |
2 |
| - |
3 |
| -###jdk1.5以上版本 |
4 |
| -```java |
5 |
| -for (Entry<String, String> entry : map.entrySet()){ |
6 |
| - System.out.println(entry.getKey() + "/" + entry.getValue()); |
7 |
| -} |
8 |
| -``` |
9 |
| -需要 import java.util.Map.Entry; |
10 |
| - |
11 |
| -###jdk1.4以下版本 |
12 |
| -```java |
13 |
| -Iterator entries = myMap.entrySet().iterator(); |
14 |
| -while (entries.hasNext()) { |
15 |
| - Entry thisEntry = (Entry) entries.next(); |
16 |
| - Object key = thisEntry.getKey(); |
17 |
| - Object value = thisEntry.getValue(); |
18 |
| -} |
19 |
| -``` |
20 |
| - |
21 |
| -stackoverflow链接: |
22 |
| -http://stackoverflow.com/questions/1066589/iterate-through-a-hashmap |
| 1 | +# HashMap遍历 # |
| 2 | + |
| 3 | +在Java中有多种遍历HashMAp的方法。让我们回顾一下最常见的方法和它们各自的优缺点。由于所有的Map都实现了Map接口,所以接下来方法适用于所有Map接口的图的实现(如:HaspMap,TreeMap,LinkedMap,HashTable,etc) |
| 4 | + |
| 5 | +## 方法#1 使用For-Each迭代entries ## |
| 6 | + |
| 7 | +这是最常见的方法,并在大多数情况下更可取的。当你在循环中需要使用Map的键和值时,就可以使用这个方法 |
| 8 | + |
| 9 | + Map<Integer, Integer> map = new HashMap<Integer, Integer>(); |
| 10 | + for(Map.Entry<Integer, Integer> entry : map.entrySet()){ |
| 11 | + System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue()) |
| 12 | + } |
| 13 | + |
| 14 | +注意:For-Each循环是Java5新引入的,所以只能在Java5以上的版本中使用。如果你遍历的map是null的话,For-Each循环会抛出NullPointerException异常,所以在遍历之前你应该判断是否为空引用。 |
| 15 | + |
| 16 | +## 方法#2 使用For-Each迭代keys和values ## |
| 17 | + |
| 18 | +如果你只需要用到map的keys或values时,你可以遍历KeySet或者values代替entrySet |
| 19 | + |
| 20 | + Map<Integer, Integer> map = new HashMap<Integer, Integer>(); |
| 21 | + |
| 22 | + //iterating over keys only |
| 23 | + for (Integer key : map.keySet()) { |
| 24 | + System.out.println("Key = " + key); |
| 25 | + } |
| 26 | + |
| 27 | + //iterating over values only |
| 28 | + for (Integer value : map.values()) { |
| 29 | + System.out.println("Value = " + value); |
| 30 | + } |
| 31 | + |
| 32 | +这个方法比entrySet迭代具有轻微的性能优势(大约快10%)并且代码更简洁 |
| 33 | + |
| 34 | +## 方法#3 使用Iterator迭代 ## |
| 35 | + |
| 36 | +使用泛型 |
| 37 | + |
| 38 | + Map<Integer, Integer> map = new HashMap<Integer, Integer>(); |
| 39 | + Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator(); |
| 40 | + while (entries.hasNext()) { |
| 41 | + Map.Entry<Integer, Integer> entry = entries.next(); |
| 42 | + System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); |
| 43 | + } |
| 44 | + |
| 45 | +不适用泛型 |
| 46 | + |
| 47 | + Map map = new HashMap(); |
| 48 | + Iterator entries = map.entrySet().iterator(); |
| 49 | + while (entries.hasNext()) { |
| 50 | + Map.Entry entry = (Map.Entry) entries.next(); |
| 51 | + Integer key = (Integer)entry.getKey(); |
| 52 | + Integer value = (Integer)entry.getValue(); |
| 53 | + System.out.println("Key = " + key + ", Value = " + value); |
| 54 | + } |
| 55 | + |
| 56 | +你可以使用同样的技术迭代keyset或者values |
| 57 | + |
| 58 | +这个似乎有点多余但它具有自己的优势。首先,它是遍历老java版本map的唯一方法。另外一个重要的特性是可以让你在迭代的时候从map中删除entries的(通过调用iterator.remover())唯一方法.如果你试图在For-Each迭代的时候删除entries,你将会得到unpredictable resultes 异常。 |
| 59 | + |
| 60 | +从性能方法看,这个方法等价于使用For-Each迭代 |
| 61 | + |
| 62 | +## 方法#4 迭代keys并搜索values(低效的) ## |
| 63 | + |
| 64 | + Map<Integer, Integer> map = new HashMap<Integer, Integer>(); |
| 65 | + for (Integer key : map.keySet()) { |
| 66 | + Integer value = map.get(key); |
| 67 | + System.out.println("Key = " + key + ", Value = " + value); |
| 68 | + } |
| 69 | + |
| 70 | +这个方法看上去比方法#1更简洁,但是实际上它更慢更低效,通过key得到value值更耗时(这个方法在所有实现map接口的map中比方法#1慢20%-200%)。如果你安装了FindBugs,它将检测并警告你这是一个低效的迭代。这个方法应该避免 |
| 71 | + |
| 72 | +## 总结 ## |
| 73 | + |
| 74 | +如果你只需要使用key或者value使用方法#2,如果你坚持使用java的老版本(java 5 以前的版本)或者打算在迭代的时候移除entries使用方法#3,另外的话使用方法#1,尽量避免出现方法#1的情况 |
0 commit comments