如果我有一个在 Java 中实现 Map
接口的对象,并且我希望遍历其中包含的每一对,那么遍历映射的最有效方法是什么?
元素的顺序是否取决于我对接口的特定地图实现?
Map<String, String> map = ...
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
在 Java 10+ 上:
for (var entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
为了总结其他答案并将它们与我所知道的结合起来,我找到了 10 种主要方法来做到这一点(见下文)。另外,我写了一些性能测试(见下面的结果)。例如,如果我们想找到一个映射的所有键和值的总和,我们可以这样写:
使用迭代器和 Map.Entry long i = 0; Iterator
性能测试(模式 = AverageTime,系统 = Windows 8.1 64 位,Intel i7-4790 3.60 GHz,16 GB)
对于小地图(100个元素),得分为0.308是最佳基准模式CNT分数错误单元test3_usishandForeachAndJava8 AVGT 10 0.308±0.021 µs/op test10_usistereclipsemap avgt 10 0.309±0.009 µs/op test1_usit1_usis1_Usist1_Usist1_Usist1_UsishiLeandmmapenter Avgt 10.380±0.380±0.380±0.380±0.380± 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 For a map with 10000 elements, score 37.606 is the best 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 平均 10 51.406 ± 1.032 µs/op test1_UsingWhileAndMapEntry 平均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对于具有100000个元素的地图,得分为1184.767是最佳基准模式CNT分数错误单元test1_usishileandmapentry avgt 10 1184.767±332.968 µs/op test10_usistereclipseclipsemap avggt 10 1191.735±304.273 µs/optry 8 33.35; 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/操作
图表(性能测试取决于地图大小)
https://i.stack.imgur.com/17VGh.png
表(性能测试取决于地图大小)
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 上。
long sum = 0; map.forEach( /* accumulate in variable sum*/);
捕获 sum
长,这可能比例如 stream.mapToInt(/*whatever*/).sum
慢。当然,您不能总是避免捕获状态,但这可能是对替补席的合理补充。
x±e
的测试结果意味着在从 x-e
到 x+e
的区间内有结果,因此最快的结果 (1184.767±332.968
) 的范围是从 852
到 1518
,而第二慢的 ( 1706.676±436.867
) 在 1270
和 2144
之间运行,因此结果仍然显着重叠。现在看看最慢的结果 3289.866±1445.564
,这意味着在 1844
和 4735
之间存在分歧,您知道这些测试结果毫无意义。
while
与 for
循环并不是一种不同的迭代技术。我很惊讶他们在你的测试中会有这样的差异——这表明测试没有正确地与与你打算测试的事物无关的外部因素隔离开来。
#8
是一个糟糕的例子,因为 parallel
现在添加到 i
时会出现竞争条件。
在 Java 8 中,您可以使用新的 lambdas 功能来干净、快速地完成它:
Map<String,String> map = new HashMap<>();
map.put("SomeKey", "SomeValue");
map.forEach( (k,v) -> [do something with key and value] );
// such as
map.forEach( (k,v) -> System.out.println("Key: " + k + ": Value: " + v));
k
和 v
的类型将由编译器推断,不再需要使用 Map.Entry
。
十分简单!
map.entrySet().stream()
docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html 返回的条目使用流 API
是的,顺序取决于具体的 Map 实现。
@ScArcher2 has the more elegant Java 1.5 syntax。在 1.4 中,我会做这样的事情:
Iterator entries = myMap.entrySet().iterator();
while (entries.hasNext()) {
Entry thisEntry = (Entry) entries.next();
Object key = thisEntry.getKey();
Object value = thisEntry.getValue();
// ...
}
for
构造用作 for (Entry e : myMap.entrySet)
将不允许您修改集合,但 @HanuAthena 提到的示例应该可以工作,因为它为您提供了范围内的 Iterator
。 (除非我遗漏了什么……)
Entry thisEntry = (Entry) entries.next();
上给我错误:无法识别 Entry
。那是别的东西的伪代码吗?
java.util.Map.Entry
。
迭代地图的典型代码是:
Map<String,Thing> map = ...;
for (Map.Entry<String,Thing> entry : map.entrySet()) {
String key = entry.getKey();
Thing thing = entry.getValue();
...
}
HashMap
是规范的 map 实现,不做任何保证(或者如果没有对其执行变异操作,它不应该更改顺序)。 SortedMap
将根据键的自然顺序或 Comparator
(如果提供)返回条目。 LinkedHashMap
将根据其构造方式以插入顺序或访问顺序返回条目。 EnumMap
以键的自然顺序返回条目。
(更新:我认为这不再正确。)注意,IdentityHashMap
entrySet
迭代器目前有一个特殊的实现,它为 entrySet
中的每个项目返回相同的 Map.Entry
实例!但是,每次新迭代器前进时,都会更新 Map.Entry
。
LinkedHashMap
计数。通过iterator
、spliterator
、entrySet
等,不修改顺序。
使用迭代器和泛型的示例:
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();
// ...
}
Iterator
放在 for 循环中以限制其范围。
for (Iterator<Map.Entry<K, V>> entries = myMap.entrySet().iterator(); entries.hasNext(); ) { Map.Entry<K, V> entry = entries.next(); }
。通过使用该构造,我们将(变量的可见性)entries
的范围限制为 for 循环。
这是一个两部分的问题:
如何迭代 Map 的条目 - @ScArcher2 answered 完美。
什么是迭代顺序 - 如果您只是使用 Map
,那么严格来说,没有顺序保证。所以你不应该真正依赖任何实现给出的顺序。但是,SortedMap
接口扩展了 Map
并提供了您正在寻找的内容 - 实现将提供一致的排序顺序。
NavigableMap
是另一个有用的扩展 - 这是一个 SortedMap
,它具有额外的方法,用于根据条目在键集中的有序位置查找条目。因此,这可能会首先消除迭代的需要 - 您可能能够在使用 higherEntry
、lowerEntry
、ceilingEntry
或 floorEntry
方法后找到您所在的特定 entry
。 descendingMap
方法甚至为您提供了反转遍历顺序 的显式方法。
有几种方法可以遍历 map。
这是通过在 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 毫秒
我提到了this link
。
仅供参考,如果您只对地图的键/值而不感兴趣,也可以使用 map.keySet()
和 map.values()
。
正确的方法是使用公认的答案,因为它是最有效的。我发现下面的代码看起来更干净一些。
for (String key: map.keySet()) {
System.out.println(key + "/" + map.get(key));
}
O(1) = 2*O(1)
几乎是大 O 符号的定义。你是对的,它运行得有点慢,但就复杂性而言,它们是相同的。
2
,因为遍历 entrySet()
根本不需要查找;它只是所有条目的线性遍历。相比之下,遍历 keySet()
并执行每个键的查找需要每个键 一个 查找,因此我们在这里讨论零查找与 n 查找,< i>n 是 Map
的大小。所以这个因素远远超出了2
......
hashcode % capacity
相同时已经发生冲突。从 Java 8 开始,具有相同 hashcode % capacity
但不同 hashcode
或为 Comparable
的项目的复杂性回落到 O(log n)
并且只有具有相同哈希码且不是 Comparable
的键强加 O(n)
复杂。但实际上查找的复杂度可能超过 O(1)
的说法仍然成立。
使用 Java 8,您可以使用 forEach 和 lambda 表达式迭代 Map,
map.forEach((k, v) -> System.out.println((k + ":" + v)));
对于 Eclipse Collections,您将在 MapIterable
接口上使用 forEachKeyValue
方法,该方法由 MutableMap
和 ImmutableMap
接口及其实现继承。
MutableBag<String> result = Bags.mutable.empty();
MutableMap<Integer, String> map = Maps.mutable.of(1, "One", 2, "Two", 3, "Three");
map.forEachKeyValue((key, value) -> result.add(key + value));
Assert.assertEquals(Bags.mutable.of("1One", "2Two", "3Three"), result);
使用匿名内部类,您可以编写如下代码:
final MutableBag<String> result = Bags.mutable.empty();
MutableMap<Integer, String> map = Maps.mutable.of(1, "One", 2, "Two", 3, "Three");
map.forEachKeyValue(new Procedure2<Integer, String>()
{
public void value(Integer key, String value)
{
result.add(key + value);
}
});
Assert.assertEquals(Bags.mutable.of("1One", "2Two", "3Three"), result);
注意:我是 Eclipse Collections 的提交者。
理论上,最有效的方式将取决于 Map 的实现。执行此操作的官方方法是调用 map.entrySet()
,它返回一组 Map.Entry
,每个 Map.Entry
包含一个键和一个值(entry.getKey()
和 entry.getValue()
)。
在一个特殊的实现中,使用 map.keySet()
、map.entrySet()
或其他东西可能会有所不同。但我想不出为什么有人会这样写。很可能它对你所做的事情没有任何影响。
是的,顺序将取决于实现 - 以及(可能)插入顺序和其他难以控制的因素。
[编辑] 我最初写了 valueSet()
,但当然 entrySet()
实际上是答案。
爪哇 8
我们有接受 lambda expression 的 forEach
方法。我们还有 stream 个 API。考虑一张地图:
Map<String,String> sample = new HashMap<>();
sample.put("A","Apple");
sample.put("B", "Ball");
遍历键:
sample.keySet().forEach((k) -> System.out.println(k));
迭代值:
sample.values().forEach((v) -> System.out.println(v));
迭代条目(使用 forEach 和 Streams):
sample.forEach((k,v) -> System.out.println(k + ":" + v));
sample.entrySet().stream().forEach((entry) -> {
Object currentKey = entry.getKey();
Object currentValue = entry.getValue();
System.out.println(currentKey + ":" + currentValue);
});
流的优点是如果我们愿意,它们可以很容易地并行化。我们只需要使用 parallelStream()
代替上面的 stream()
。
forEachOrdered
vs forEach
与流? forEach
不遵循遇到顺序(如果已定义),并且本质上是不确定性的,而 forEachOrdered
确实如此。所以 forEach
不保证订单会被保留。另请查看 this 了解更多信息。
Lambda 表达式 Java 8
在 Java 1.8 (Java 8) 中,通过使用聚合操作(流操作)中的 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 Docs 的文档链接。有关 Lambda 的更多信息,请参阅此 link,必须阅读 Aggregate Operations,对于 Spliterator,请参阅此 link。
爪哇 8:
您可以使用 lambda 表达式:
myMap.entrySet().stream().forEach((entry) -> {
Object currentKey = entry.getKey();
Object currentValue = entry.getValue();
});
如需更多信息,请关注 this。
myMap.forEach( (currentKey,currentValue) -> /* action */ );
更加简洁。
在 Map 中,可以迭代 keys
和/或 values
和/或 both (e.g., entrySet)
取决于一个人的兴趣_喜欢:
遍历地图的键 -> keySet(): Map
此外,有 3 种不同的方法可以遍历 HashMap。它们如下:
//1.
for (Map.Entry entry : hm.entrySet()) {
System.out.print("key,val: ");
System.out.println(entry.getKey() + "," + entry.getValue());
}
//2.
Iterator iter = hm.keySet().iterator();
while(iter.hasNext()) {
Integer key = (Integer)iter.next();
String val = (String)hm.get(key);
System.out.println("key,val: " + key + "," + val);
}
//3.
Iterator it = hm.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Integer key = (Integer)entry.getKey();
String val = (String)entry.getValue();
System.out.println("key,val: " + key + "," + val);
}
用 Java 1.4 试试这个:
for( Iterator entries = myMap.entrySet().iterator(); entries.hasNext();){
Entry entry = (Entry) entries.next();
System.out.println(entry.getKey() + "/" + entry.getValue());
//...
}
排序将始终取决于特定的地图实现。使用 Java 8,您可以使用以下任何一种:
map.forEach((k,v) -> { System.out.println(k + ":" + v); });
或者:
map.entrySet().forEach((e) -> {
System.out.println(e.getKey() + " : " + e.getValue());
});
结果将是相同的(相同的顺序)。地图支持的 entrySet,因此您获得相同的订单。第二个很方便,因为它允许您使用 lambda,例如,如果您只想打印大于 5 的 Integer 对象:
map.entrySet()
.stream()
.filter(e-> e.getValue() > 5)
.forEach(System.out::println);
下面的代码显示了通过 LinkedHashMap 和普通 HashMap 的迭代(示例)。你会看到顺序的不同:
public class HMIteration {
public static void main(String[] args) {
Map<Object, Object> linkedHashMap = new LinkedHashMap<>();
Map<Object, Object> hashMap = new HashMap<>();
for (int i=10; i>=0; i--) {
linkedHashMap.put(i, i);
hashMap.put(i, i);
}
System.out.println("LinkedHashMap (1): ");
linkedHashMap.forEach((k,v) -> { System.out.print(k + " (#="+k.hashCode() + "):" + v + ", "); });
System.out.println("\nLinkedHashMap (2): ");
linkedHashMap.entrySet().forEach((e) -> {
System.out.print(e.getKey() + " : " + e.getValue() + ", ");
});
System.out.println("\n\nHashMap (1): ");
hashMap.forEach((k,v) -> { System.out.print(k + " (#:"+k.hashCode() + "):" + v + ", "); });
System.out.println("\nHashMap (2): ");
hashMap.entrySet().forEach((e) -> {
System.out.print(e.getKey() + " : " + e.getValue() + ", ");
});
}
}
输出:
LinkedHashMap (1):
10 (#=10):10, 9 (#=9):9, 8 (#=8):8, 7 (#=7):7, 6 (#=6):6, 5 (#=5):5, 4 (#=4):4, 3 (#=3):3, 2 (#=2):2, 1 (#=1):1, 0 (#=0):0,
LinkedHashMap (2):
10 : 10, 9 : 9, 8 : 8, 7 : 7, 6 : 6, 5 : 5, 4 : 4, 3 : 3, 2 : 2, 1 : 1, 0 : 0,
HashMap (1):
0 (#:0):0, 1 (#:1):1, 2 (#:2):2, 3 (#:3):3, 4 (#:4):4, 5 (#:5):5, 6 (#:6):6, 7 (#:7):7, 8 (#:8):8, 9 (#:9):9, 10 (#:10):10,
HashMap (2):
0 : 0, 1 : 1, 2 : 2, 3 : 3, 4 : 4, 5 : 5, 6 : 6, 7 : 7, 8 : 8, 9 : 9, 10 : 10,
Java 8 最紧凑:
map.entrySet().forEach(System.out::println);
如果我有一个在 Java 中实现 Map 接口的对象,并且我希望遍历其中包含的每一对,那么遍历映射的最有效方法是什么?
如果循环键的效率是您的应用程序的优先事项,则选择一个 Map
实现,以按您希望的顺序维护键。
元素的顺序是否取决于我对接口的特定地图实现?
是的,一点没错。
一些 Map 实现承诺一定的迭代顺序,而另一些则没有。
Map 的不同实现保持键值对的不同顺序。
请参阅我创建的此表,该表总结了与 Java 11 捆绑的各种 Map
实现。具体来说,请注意 iteration order 列。单击/点击以缩放。
https://i.stack.imgur.com/4z5Fb.png
您可以看到有四个Map
实现维护一个顺序:
树状图
并发跳过列表映射
LinkedHashMap
枚举映射
导航地图接口
其中两个实现了 NavigableMap
接口:TreeMap
& ConcurrentSkipListMap
。
较旧的 SortedMap
接口被较新的 NavigableMap
接口有效地取代。但是您可能会发现仅实现旧接口的第 3 方实现。
自然秩序
如果您想要一个 Map
保持其对按键的“自然顺序”排列,请使用 TreeMap
或 ConcurrentSkipListMap
。术语“自然顺序”是指键的类实现Comparable
。 compareTo
方法返回的值用于排序比较。
定制订单
如果您想为要用于维护排序顺序的键指定自定义排序例程,请传递适合您的键类的 Comparator
实现。使用 TreeMap
或 ConcurrentSkipListMap
,传递您的 Comparator
。
原始广告订单
如果您希望成对的地图按照您将它们插入地图时的原始顺序保留,请使用 LinkedHashMap
。
枚举定义顺序
如果您使用 DayOfWeek
或 Month
等枚举作为键,请使用 EnumMap
类。这个类不仅高度被优化为使用非常少的内存并且运行非常快,它还按照枚举定义的顺序维护你的对。以DayOfWeek
为例,迭代时首先找到DayOfWeek.MONDAY
的key,最后找到DayOfWeek.SUNDAY
的key。
其他注意事项
在选择 Map
实现时,还要考虑:
空值。一些实现禁止/接受 NULL 作为键和/或值。
并发。如果要跨线程操作映射,则必须使用支持并发的实现。或者用 Collections::synchronizedMap 包装地图(不太可取)。
这两个考虑因素都包含在上面的图表中。
EnumMap
而 +1,因为这是我第一次听说它。在很多情况下,这可能会派上用场。
如果您有一个通用的无类型地图,您可以使用:
Map map = new HashMap();
for (Map.Entry entry : ((Set<Map.Entry>) map.entrySet())) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
public class abcd{
public static void main(String[] args)
{
Map<Integer, String> testMap = new HashMap<Integer, String>();
testMap.put(10, "a");
testMap.put(20, "b");
testMap.put(30, "c");
testMap.put(40, "d");
for (Integer key:testMap.keySet()) {
String value=testMap.get(key);
System.out.println(value);
}
}
}
或者
public class abcd {
public static void main(String[] args)
{
Map<Integer, String> testMap = new HashMap<Integer, String>();
testMap.put(10, "a");
testMap.put(20, "b");
testMap.put(30, "c");
testMap.put(40, "d");
for (Entry<Integer, String> entry : testMap.entrySet()) {
Integer key=entry.getKey();
String value=entry.getValue();
}
}
}
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 迭代解决方案是从 Java 5 到 Java 7 的 for
循环。它是:
for (String key : phnMap.keySet()) {
System.out.println("Key: " + key + " Value: " + phnMap.get(key));
}
从 Java 8 开始,您可以使用 lambda 表达式来迭代 Map。这是一个增强的 forEach
phnMap.forEach((k,v) -> System.out.println("Key: " + k + " Value: " + v));
如果你想为 lambda 写一个条件,你可以这样写:
phnMap.forEach((k,v)->{
System.out.println("Key: " + k + " Value: " + v);
if("abc".equals(k)){
System.out.println("Hello abc");
}
});
您可以使用泛型来做到这一点:
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());
}
使用 Java 8:
map.entrySet().forEach(entry -> System.out.println(entry.getValue()));
//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();
}
有很多方法可以做到这一点。下面是几个简单的步骤:
假设你有一张像这样的地图:
Map<String, Integer> m = new HashMap<String, Integer>();
然后,您可以执行以下操作来迭代地图元素。
// ********** Using an iterator ****************
Iterator<Entry<String, Integer>> me = m.entrySet().iterator();
while(me.hasNext()){
Entry<String, Integer> pair = me.next();
System.out.println(pair.getKey() + ":" + pair.getValue());
}
// *********** Using foreach ************************
for(Entry<String, Integer> me : m.entrySet()){
System.out.println(me.getKey() + " : " + me.getValue());
}
// *********** Using keySet *****************************
for(String s : m.keySet()){
System.out.println(s + " : " + m.get(s));
}
// *********** Using keySet and iterator *****************
Iterator<String> me = m.keySet().iterator();
while(me.hasNext()){
String key = me.next();
System.out.println(key + " : " + m.get(key));
}
迭代 Map 非常容易。
for(Object key: map.keySet()){
Object value= map.get(key);
//Do your stuff
}
例如,您有一个 Map<String, int> data;
for(Object key: data.keySet()){
int value= data.get(key);
}
remove
方法。如果是这种情况,this other answer 将向您展示如何操作。否则,如上面答案所示的增强循环是要走的路。map.values()
或map.keySet()
。