如果我有一个用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 8:
可以使用lambda表达式:
myMap.entrySet().stream().forEach((entry) -> {
Object currentKey = entry.getKey();
Object currentValue = entry.getValue();
});
有关详细信息,请遵循以下步骤。
有几种方法可以迭代地图。
下面是通过在map中存储一百万个键值对并将在map中进行迭代,对map中存储的公共数据集的性能进行比较。
1) 在每个循环中使用entrySet()
for (Map.Entry<String,Integer> entry : testMap.entrySet()) {
entry.getKey();
entry.getValue();
}
50毫秒
2) 在每个循环中使用keySet()
for (String key : testMap.keySet()) {
testMap.get(key);
}
76毫秒
3) 使用entrySet()和迭代器
Iterator<Map.Entry<String,Integer>> itr1 = testMap.entrySet().iterator();
while(itr1.hasNext()) {
Map.Entry<String,Integer> entry = itr1.next();
entry.getKey();
entry.getValue();
}
50毫秒
4) 使用keySet()和迭代器
Iterator itr2 = testMap.keySet().iterator();
while(itr2.hasNext()) {
String key = itr2.next();
testMap.get(key);
}
75毫秒
我已经提到了这个链接。
使用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));
为了总结其他答案并将它们与我所知道的结合起来,我找到了10种主要的方法(见下文)。此外,我还编写了一些性能测试(见下面的结果)。例如,如果我们想找到映射的所有键和值的总和,我们可以写:
使用迭代器和Map.Entry长i=0;迭代器<Map.Entry<Integer,Integer>>it=Map.entrySet().iiterator();while(it.hasNext()){Map.Entry<Integer,Integer>pair=it.next();i+=pair.getKey()+pair.getValue();}使用foreach和Map.Entry长i=0;for(Map.Entry<Integer,Integer>对:Map.entrySet()){i+=pair.getKey()+pair.getValue();}使用Java 8中的forEach最终长[]i={0};map.forEach((k,v)->i[0]+=k+v);使用keySet和foreach长i=0;for(整数键:map.keySet()){i+=键+map.get(键);}使用keySet和迭代器长i=0;Iterator<Integer>itr2=map.keySet().Iterator();而(itr2.hasNext()){整数键=itr2.next();i+=键+map.get(键);}使用for和Map.Entry长i=0;for(Iterator<Map.Entry<Integer,Integer>>条目=Map.entrySet().Iterator();entries.hasNext();){Map.Entry<Integer,Integer>Entry=entries.next();i+=entry.getKey()+entry.getValue();}使用Java 8流API最终长[]i={0};map.entrySet().stream().forEach(e->i[0]+=e.getKey()+e.getValue());并行使用Java 8流API最终长[]i={0};map.entrySet().stream().allel().forEach(e->i[0]+=e.getKey()+e.getValue());使用Apache集合的IterableMap长i=0;MapIterator<Integer,Integer>it=iterableMap.MapIterator();while(it.hasNext()){i+=it.next()+it.getValue();}使用Eclipse(CS)集合的MutableMap最终长[]i={0};mutableMap.forEachKeyValue((key,value)->{i[0]+=键+值;});
性能测试(模式=平均时间,系统=Windows 8.1 64位,Intel i7-4790 3.60 GHz,16 GB)
对于小地图(100个元素),得分0.308是最好的基准模式控制分数误差单位测试3_UsingForEachAndJava8平均值10 0.308±0.021µs/op测试10_UsingEclipseMap平均值10 0.309±0.009µs/optest1_UsingWhileAndMapEntry平均值10 0.380±0.014µs/optest6_SingingForAndIterator平均值10 0.387±0.016µs/optest2_UsingForEachAndMapEntry平均值10 0.391±0.023µs/op测试7_UsingJava8StreamApi平均值10 0.510±0.014µs/optest9_UsingApacheIterableMap平均值10 0.524±0.008µs/optest4_UsingKeySetAndForEach平均值10 0.816±0.026µs/optest5_UsingKeySetAndIterator平均值10 0.863±0.025µs/optest8_UsingJava8StreamApiParallel平均值10 5.552±0.185µs/op对于包含10000个元素的地图,得分37.606是最好的基准模式控制分数误差单位测试10_UsingEclipseMap平均值10 37.606±0.790µs/op测试3_使用EachAndJava8平均值10 50.368±0.887µs/op测试6_SingingForAndIterator平均值10 50.332±0.507µs/optest2_UsingForEachAndMapEntry平均值10 51.406±1.032µs/op测试1_UsingWhileAndMapEntry平均值10 52.538±2.431µs/op测试7_UsingJava8StreamApi平均值10 54.464±0.712µs/optest4_UsingKeySetAndForEach平均值10 79.016±25.345µs/optest5_UsingKeySetAndIterator平均值10 91.105±10.220µs/optest8_UsingJava8StreamApiParallel平均值10 112.511±0.365µs/optest9_UsingApacheIterableMap平均值10 125.714±1.935µs/op对于包含100000个元素的地图,得分1184.767是最好的基准模式控制分数误差单位测试1_UsingWhileAndMapEntry平均值10 1184.767±332.968µs/op测试10_UsingEclipseMap平均值10 1191.735±304.273µs/optest2_UsingForEachAndMapEntry平均值10 1205.815±366.043µs/op测试6_SingingForAndIterator平均值10 1206.873±367.272µs/optest8_UsingJava8StreamApiParallel平均值10 1485.895±233.143µs/optest5_UsingKeySetAndIterator平均值10 1540.281±357.497µs/optest4_UsingKeySetAndForEach平均值10 1593.342±294.417µs/op测试3_UsingForEachAndJava8平均值10 1666.296±126.443µs/op测试7_UsingJava8StreamApi平均值10 1706.676±436.867µs/optest9_UsingApacheIterableMap平均值10 3289.866±1445.564µs/op
图表(性能测试取决于地图大小)
表(性能测试取决于地图大小)
100 600 1100 1600 2100
test10 0.333 1.631 2.752 5.937 8.024
test3 0.309 1.971 4.147 8.147 10.473
test6 0.372 2.190 4.470 8.322 10.531
test1 0.405 2.237 4.616 8.645 10.707
test2 0.376 2.267 4.809 8.403 10.910
test7 0.473 2.448 5.668 9.790 12.125
test9 0.565 2.830 5.952 13.220 16.965
test4 0.808 5.012 8.813 13.939 17.407
test5 0.810 5.104 8.533 14.064 17.422
test8 5.173 12.499 17.351 24.671 30.403
所有测试都在GitHub上。
Lambda表达式Java 8
在Java1.8(Java8)中,通过使用Aggregate操作(Stream操作)中的forEach方法,这变得更加容易,它看起来类似于Iterable接口中的迭代器。
只需将下面的粘贴语句复制到代码中,并将HashMap变量从hm重命名为HashMap变量,即可打印出键值对。
HashMap<Integer,Integer> hm = new HashMap<Integer, Integer>();
/*
* Logic to put the Key,Value pair in your HashMap hm
*/
// Print the key value pair in one line.
hm.forEach((k, v) -> System.out.println("key: " + k + " value:" + v));
// Just copy and paste above line to your code.
下面是我尝试使用Lambda表达式的示例代码。这东西太酷了。必须尝试。
HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
Random rand = new Random(47);
int i = 0;
while(i < 5) {
i++;
int key = rand.nextInt(20);
int value = rand.nextInt(50);
System.out.println("Inserting key: " + key + " Value: " + value);
Integer imap = hm.put(key, value);
if( imap == null) {
System.out.println("Inserted");
} else {
System.out.println("Replaced with " + imap);
}
}
hm.forEach((k, v) -> System.out.println("key: " + k + " value:" + v));
Output:
Inserting key: 18 Value: 5
Inserted
Inserting key: 13 Value: 11
Inserted
Inserting key: 1 Value: 29
Inserted
Inserting key: 8 Value: 0
Inserted
Inserting key: 2 Value: 7
Inserted
key: 1 value:29
key: 18 value:5
key: 2 value:7
key: 8 value:0
key: 13 value:11
同样也可以使用Spliterator。
Spliterator sit = hm.entrySet().spliterator();
更新
包括指向Oracle文档的文档链接。有关Lambda的更多信息,请访问此链接,必须阅读聚合操作,对于Spliterator,请访问该链接。