如何有效地遍历"地图"中的每个条目?

时间:2020-03-05 18:48:32  来源:igfitidea点击:

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

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

解决方案

回答

是的,顺序取决于特定的Map实现。

@ ScArcher2具有更优雅的Java 1.5语法。在1.4中,我将执行以下操作:

Iterator entries = myMap.entrySet().iterator();
while (entries.hasNext()) {
  Entry thisEntry = (Entry) entries.next();
  Object key = thisEntry.getKey();
  Object value = thisEntry.getValue();
  // ...
}

回答

Map<String, String> map = ...
for (Map.Entry<String, String> entry : map.entrySet())
{
    System.out.println(entry.getKey() + "/" + entry.getValue());
}

回答

从理论上讲,最有效的方法将取决于Map的实现方式。官方的方法是调用" map.entrySet()",它返回一组" Map.Entry",每个集合都包含一个键和一个值(" entry.getKey()"和" entry.getValue" ()`)。

在特有的实现中,无论使用map.keySet(),`map.entrySet()还是其他方法,都可能会有所不同。但我想不出有人会这样写的原因。最有可能的是它对我们所做的工作没有影响。

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

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

回答

遍历地图的典型代码是:

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"以键的自然顺序返回条目。

(更新:我认为这不再成立了。)注意,IdentityHashMapentrySet迭代器当前具有一个特殊的实现,它为entrySet中的每个项目返回相同的Map.Entry`实例!但是,每次新的迭代器前进时,都会更新Map.Entry。

回答

这是一个两部分的问题:

如何遍历Map @ ScArcher2的条目已经很好地回答了这一问题。

如果仅使用Map,则迭代的顺序是什么,严格来说,没有顺序保证。因此,我们不应真正依赖任何实现所给出的顺序。但是," SortedMap"接口扩展了" Map",并提供了我们正在寻找的实现,而这些给定了一致的排序顺序。

" NavigableMap"是另一个有用的扩展,它是" SortedMap",它具有其他方法,可以根据键集中的有序位置查找条目。因此潜在地,这可以消除对迭代的需要,首先我们可以在使用" higherEntry"," lowerEntry"," ceilingEntry"或者" floorEntry"方法之后找到特定的" entry"。 descendingMap方法甚至为我们提供了一种反转遍历顺序的显式方法。

回答

仅供参考,如果我们仅对地图的键/值感兴趣,而对其他键/值不感兴趣,则也可以使用map.keySet()和map.values()。

回答

正确的方法是使用公认的答案,因为它是最有效的。我发现以下代码看起来更干净。

for (String key: map.keySet()) {
   System.out.println(key + "/" + map.get(key));
}

回答

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

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();
  // ...
}

回答

使用Java 1.4尝试一下:

for( Iterator entries = myMap.entrySet().iterator(); entries.hasNext();){

  Entry entry = (Entry) entries.next();

  System.out.println(entry.getKey() + "/" + entry.getValue());

  //...
}