如果我有一个用Java实现Map接口的对象,并且我希望对其中包含的每一对进行迭代,那么最有效的方法是什么?

元素的顺序是否取决于我对接口的特定映射实现?


当前回答

从Java10开始,您可以使用局部变量推理(也称为“var”)来减少许多现有答案的臃肿。例如:

for (var entry : map.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

其他回答

如果要按元素添加的顺序遍历映射,请使用LinkedHashMap,而不是仅使用map。

这种方法在过去对我很有效:

LinkedHashMap<String,Integer> test=new LinkedHashMap();

test.put("foo",69);
test.put("bar",1337);

for(int i=0;i<test.size();i++){
    System.out.println(test.get(test.keySet().toArray()[i]));
}

输出:

69
1337

使用Java 7

Map<String,String> sampleMap = new HashMap<>();
for (sampleMap.Entry<String,String> entry : sampleMap.entrySet()) {
    String key = entry.getKey();
    String value = entry.getValue();

    /* your Code as per the Business Justification  */

}

使用Java 8

Map<String,String> sampleMap = new HashMap<>();

sampleMap.forEach((k, v) -> System.out.println("Key is :  " + k + " Value is :  " + v));

在地图上迭代的典型代码是:

Map<String,Thing> map = ...;
for (Map.Entry<String,Thing> entry : map.entrySet()) {
    String key = entry.getKey();
    Thing thing = entry.getValue();
    ...
}

HashMap是规范映射实现,不做任何保证(或者,如果不对其执行任何变异操作,则不应更改顺序)。SortedMap将根据键的自然顺序或Comparator(如果提供)返回条目。LinkedHashMap将按照插入顺序或访问顺序返回条目,具体取决于它的构造方式。EnumMap以键的自然顺序返回条目。

(更新:我认为这不再是真的。)注意,IdentityHashMap entrySet迭代器目前有一个特殊的实现,它为entrySet中的每个项返回相同的Map.Entry实例!然而,每次新迭代器推进Map.Entry时都会更新。

理论上,最有效的方法将取决于Map的实现。官方的方法是调用map.entrySet(),它返回一组map.Entry,其中每个包含一个键和一个值(Entry.getKey()和Entry.getValue())。

在特殊的实现中,使用map.keySet()、map.entrySet()或其他方法可能会有所不同。但我想不出为什么有人会这样写。最有可能的是,你所做的对绩效没有影响。

是的,顺序将取决于实现,以及(可能)插入顺序和其他难以控制的因素。

[编辑]我最初写了valueSet(),但当然entrySet()实际上是答案。

使用迭代器和泛型的示例:

Iterator<Map.Entry<String, String>> entries = myMap.entrySet().iterator();
while (entries.hasNext()) {
  Map.Entry<String, String> entry = entries.next();
  String key = entry.getKey();
  String value = entry.getValue();
  // ...
}