如何有效地遍历"地图"中的每个条目?
如果我有一个用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()); //... }