本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看<活动链接>
提问:如何有效地遍历Java Map中的每个条目?
如果我有一个用Java实现Map接口的对象,并且希望对其中包含的每一对(key,value)进行迭代,那么遍历该map实例的最有效方法是什么?
元素的顺序是否取决于我对接口的特定映射实现(即hash方法)?
总结回答:
- 使用迭代器和Map.Entry
long i = 0;
Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, Integer> pair = it.next();
i += pair.getKey() + pair.getValue();
}
- 使用foreach和Map.Entry
Map<String, String> map = ...
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
- 使用Java 8新特性Lambda表达式以及forEach
final long[] i = {0};
map.forEach((k, v) -> i[0] += k + v);
- 用keySet代替Map.Entry
- 使用for和Map.Entry
long i = 0;
for (Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator(); entries.hasNext(); ) {
Map.Entry<Integer, Integer> entry = entries.next();
i += entry.getKey() + entry.getValue();
}
- 使用Java 8 Stream API
final long[] i = {0};
map.entrySet().stream().forEach(e -> i[0] += e.getKey() + e.getValue());
- 使用Apache Collections的IterableMap
long i = 0;
MapIterator<Integer, Integer> it = iterableMap.mapIterator();
while (it.hasNext()) {
i += it.next() + it.getValue();
}
上述方法总结了如何遍历,接下来回答map遍历顺序与什么有关
例子代码如下
public static void main(String[] args) {
HashMap<Integer, Integer> hp = new HashMap<>();
hp.put(1,1);
hp.put(3,3);
hp.put(0,0);
hp.put(2,2);
// long i = 0;
Iterator<Map.Entry<Integer, Integer>> it = hp.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, Integer> pair = it.next();
System.out.println(pair.getKey() + " : " + pair.getValue());
//i += pair.getKey() + pair.getValue();
}
}
输出有:
0 : 0
1 : 1
2 : 2
3 : 3
得出结论,map遍历顺序与插入顺序无关。
至于遍历顺序是什么,严格来说,是没有顺序的,因为我们并不是所有的map都是Integer为key。(不过可以保证每次遍历的顺序是一样的)