如果我有一个对象在 Java 中实现了 Map
接口,并且我希望遍历其中包含的每一对,那么遍历映射的最有效方法是什么?
元素的顺序是否取决于我为界面提供的特定地图实现?
原文由 iMack 发布,翻译遵循 CC BY-SA 4.0 许可协议
如果我有一个对象在 Java 中实现了 Map
接口,并且我希望遍历其中包含的每一对,那么遍历映射的最有效方法是什么?
元素的顺序是否取决于我为界面提供的特定地图实现?
原文由 iMack 发布,翻译遵循 CC BY-SA 4.0 许可协议
为了总结其他答案并将它们与我所知道的结合起来,我找到了 10 种主要方法(见下文)。另外,我写了一些性能测试(见下面的结果)。例如,如果我们想找到一个映射的所有键和值的总和,我们可以这样写:
使用 迭代器 和 Map.Entry
long i = 0;
Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, Integer> pair = it.next();
i += pair.getKey() + pair.getValue();
}
使用 foreach 和 Map.Entry
long i = 0;
for (Map.Entry<Integer, Integer> pair : map.entrySet()) {
i += pair.getKey() + pair.getValue();
}
从 Java 8 使用 forEach
final long[] i = {0};
map.forEach((k, v) -> i[0] += k + v);
使用 keySet 和 foreach
long i = 0;
for (Integer key : map.keySet()) {
i += key + map.get(key);
}
使用 keySet 和 迭代器
long i = 0;
Iterator<Integer> itr2 = map.keySet().iterator();
while (itr2.hasNext()) {
Integer key = itr2.next();
i += key + map.get(key);
}
使用 for 和 Map.Entry
long i = 0;
for (Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator(); entries.hasNext(); ) {
Map.Entry<Integer, Integer> entry = entries.next();
i += entry.getKey() + entry.getValue();
}
使用 Java 8 流 API
final long[] i = {0};
map.entrySet().stream().forEach(e -> i[0] += e.getKey() + e.getValue());
使用 Java 8 Stream API 并行
final long[] i = {0};
map.entrySet().stream().parallel().forEach(e -> i[0] += e.getKey() + e.getValue());
使用 IterableMap Apache Collections
long i = 0;
MapIterator<Integer, Integer> it = iterableMap.mapIterator();
while (it.hasNext()) {
i += it.next() + it.getValue();
}
使用 Eclipse (CS) 集合的 MutableMap
final long[] i = {0};
mutableMap.forEachKeyValue((key, value) -> {
i[0] += key + value;
});
性能测试(模式 = AverageTime,系统 = Windows 8.1 64 位,Intel i7-4790 3.60 GHz,16 GB)
Benchmark Mode Cnt Score Error Units
test3_UsingForEachAndJava8 avgt 10 0.308 ± 0.021 µs/op
test10_UsingEclipseMap avgt 10 0.309 ± 0.009 µs/op
test1_UsingWhileAndMapEntry avgt 10 0.380 ± 0.014 µs/op
test6_UsingForAndIterator avgt 10 0.387 ± 0.016 µs/op
test2_UsingForEachAndMapEntry avgt 10 0.391 ± 0.023 µs/op
test7_UsingJava8StreamApi avgt 10 0.510 ± 0.014 µs/op
test9_UsingApacheIterableMap avgt 10 0.524 ± 0.008 µs/op
test4_UsingKeySetAndForEach avgt 10 0.816 ± 0.026 µs/op
test5_UsingKeySetAndIterator avgt 10 0.863 ± 0.025 µs/op
test8_UsingJava8StreamApiParallel avgt 10 5.552 ± 0.185 µs/op
Benchmark Mode Cnt Score Error Units
test10_UsingEclipseMap avgt 10 37.606 ± 0.790 µs/op
test3_UsingForEachAndJava8 avgt 10 50.368 ± 0.887 µs/op
test6_UsingForAndIterator avgt 10 50.332 ± 0.507 µs/op
test2_UsingForEachAndMapEntry avgt 10 51.406 ± 1.032 µs/op
test1_UsingWhileAndMapEntry avgt 10 52.538 ± 2.431 µs/op
test7_UsingJava8StreamApi avgt 10 54.464 ± 0.712 µs/op
test4_UsingKeySetAndForEach avgt 10 79.016 ± 25.345 µs/op
test5_UsingKeySetAndIterator avgt 10 91.105 ± 10.220 µs/op
test8_UsingJava8StreamApiParallel avgt 10 112.511 ± 0.365 µs/op
test9_UsingApacheIterableMap avgt 10 125.714 ± 1.935 µs/op
Benchmark Mode Cnt Score Error Units
test1_UsingWhileAndMapEntry avgt 10 1184.767 ± 332.968 µs/op
test10_UsingEclipseMap avgt 10 1191.735 ± 304.273 µs/op
test2_UsingForEachAndMapEntry avgt 10 1205.815 ± 366.043 µs/op
test6_UsingForAndIterator avgt 10 1206.873 ± 367.272 µs/op
test8_UsingJava8StreamApiParallel avgt 10 1485.895 ± 233.143 µs/op
test5_UsingKeySetAndIterator avgt 10 1540.281 ± 357.497 µs/op
test4_UsingKeySetAndForEach avgt 10 1593.342 ± 294.417 µs/op
test3_UsingForEachAndJava8 avgt 10 1666.296 ± 126.443 µs/op
test7_UsingJava8StreamApi avgt 10 1706.676 ± 436.867 µs/op
test9_UsingApacheIterableMap avgt 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 上。
原文由 Slava Vedenin 发布,翻译遵循 CC BY-SA 4.0 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
3 回答1.7k 阅读✓ 已解决
在 Java 10+ 上: