如果我有一个用Java实现Map接口的对象,并且我希望对其中包含的每一对进行迭代,那么最有效的方法是什么?
元素的顺序是否取决于我对接口的特定映射实现?
如果我有一个用Java实现Map接口的对象,并且我希望对其中包含的每一对进行迭代,那么最有效的方法是什么?
元素的顺序是否取决于我对接口的特定映射实现?
当前回答
//Functional Oprations
Map<String, String> mapString = new HashMap<>();
mapString.entrySet().stream().map((entry) -> {
String mapKey = entry.getKey();
return entry;
}).forEach((entry) -> {
String mapValue = entry.getValue();
});
//Intrator
Map<String, String> mapString = new HashMap<>();
for (Iterator<Map.Entry<String, String>> it = mapString.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, String> entry = it.next();
String mapKey = entry.getKey();
String mapValue = entry.getValue();
}
//Simple for loop
Map<String, String> mapString = new HashMap<>();
for (Map.Entry<String, String> entry : mapString.entrySet()) {
String mapKey = entry.getKey();
String mapValue = 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());
//...
}
是的,顺序取决于特定的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();
// ...
}
如果我有一个用Java实现Map接口的对象,并且我希望对其中包含的每一对进行迭代,那么最有效的方法是什么?
如果循环键的效率是应用程序的优先事项,那么选择一个Map实现,以您所需的顺序维护键。
元素的顺序是否取决于我对接口的特定映射实现?
是的,绝对。
一些Map实现承诺一定的迭代顺序,而其他的则没有。Map的不同实现维护键值对的不同顺序。
请参见我创建的总结了与Java11捆绑的各种Map实现的表。具体来说,请注意迭代顺序列。单击/轻按以缩放。
您可以看到,有四个Map实现维护一个顺序:
树图并发跳过列表映射链接的哈希映射EnumMap(枚举映射)
NavigableMap界面
其中两个实现NavigableMap接口:TreeMap&ConcurrentSkipListMap。
旧的SortedMap界面被新的NavigableMap界面有效地取代。但您可能会发现第三方实现仅实现旧接口。
自然秩序
如果您想要一个按键的“自然顺序”排列其对的Map,请使用TreeMap或ConcurrentSkipListMap。术语“自然顺序”是指实现Comparable的键类。compareTo方法返回的值用于排序中的比较。
自定义订单
如果要为键指定自定义排序例程以用于维护排序顺序,请传递适合于键类的Comparator实现。使用TreeMap或ConcurrentSkipListMap,传递比较器。
原始插入顺序
如果您希望映射对保持在它们插入映射的原始顺序,请使用LinkedHashMap。
枚举定义顺序
如果使用诸如DayOfWeek或Month之类的枚举作为键,请使用EnumMap类。这个类不仅被高度优化以使用很少的内存并且运行非常快,它还按照枚举定义的顺序维护您的对。例如,对于DayOfWeek,DayOfWeek.MONDAY的键将在迭代时首先找到,DayOfWeek.SUNDAY的密钥将是最后一个。
其他注意事项
在选择Map实现时,还应考虑:
NULLs。某些实现禁止/接受NULL作为键和/或值。并发性。如果要跨线程操作映射,则必须使用支持并发的实现。或者使用Collections::synchronizedMap包装映射(不太可取)。
以上图表中涵盖了这两个考虑因素。
Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry element = (Map.Entry)it.next();
LOGGER.debug("Key: " + element.getKey());
LOGGER.debug("value: " + element.getValue());
}
您可以使用泛型:
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<Integer, Integer> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}