3724

如果我有一个Map在 Java 中实现接口的对象,并且我希望遍历其中包含的每一对,那么遍历映射的最有效方法是什么?

元素的顺序是否取决于我对接口的特定地图实现?

4

46 回答 46

5589
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());
}
于 2008-09-05T21:15:52.713 回答
1472

为了总结其他答案并将它们与我所知道的结合起来,我找到了 10 种主​​要方法来做到这一点(见下文)。另外,我写了一些性能测试(见下面的结果)。例如,如果我们想找到一个映射的所有键和值的总和,我们可以这样写:

  1. 使用迭代器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();
    }
    
  2. 使用foreachMap.Entry

    long i = 0;
    for (Map.Entry<Integer, Integer> pair : map.entrySet()) {
        i += pair.getKey() + pair.getValue();
    }
    
  3. 在 Java 8 中使用forEach

    final long[] i = {0};
    map.forEach((k, v) -> i[0] += k + v);
    
  4. 使用keySetforeach

    long i = 0;
    for (Integer key : map.keySet()) {
        i += key + map.get(key);
    }
    
  5. 使用keySet迭代器

    long i = 0;
    Iterator<Integer> itr2 = map.keySet().iterator();
    while (itr2.hasNext()) {
        Integer key = itr2.next();
        i += key + map.get(key);
    }
    
  6. 使用forMap.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();
    }
    
  7. 使用 Java 8流 API

    final long[] i = {0};
    map.entrySet().stream().forEach(e -> i[0] += e.getKey() + e.getValue());
    
  8. 并行使用 Java 8 Stream API

    final long[] i = {0};
    map.entrySet().stream().parallel().forEach(e -> i[0] += e.getKey() + e.getValue());
    
  9. 使用IterableMapApache Collections

    long i = 0;
    MapIterator<Integer, Integer> it = iterableMap.mapIterator();
    while (it.hasNext()) {
        i += it.next() + it.getValue();
    }
    
  10. 使用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)

  1. 对于小地图(100 个元素),得分 0.308 是最好的

    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
    
  2. 对于具有 10000 个元素的地图,得分 37.606 是最好的

    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
    
  3. 对于具有 100000 个元素的地图,得分 1184.767 是最好的

    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 上

于 2016-02-22T16:37:29.997 回答
322

在 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

十分简单!

于 2013-10-21T10:15:25.730 回答
256

是的,顺序取决于具体的 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();
  // ...
}
于 2008-09-05T21:15:19.830 回答
145

迭代地图的典型代码是:

Map<String,Thing> map = ...;
for (Map.Entry<String,Thing> entry : map.entrySet()) {
    String key = entry.getKey();
    Thing thing = entry.getValue();
    ...
}

HashMap是规范的映射实现并且不做保证(或者如果没有对其执行变异操作,它不应该更改顺序)。SortedMap将根据键的自然顺序返回条目,或者Comparator如果提供了 a 。LinkedHashMap将根据其构造方式以插入顺序或访问顺序返回条目。EnumMap以键的自然顺序返回条目。

(更新:我认为这不再正确。)注意,IdentityHashMap entrySet迭代器目前有一个特殊的实现,它为!Map.Entry中的每个项目返回相同的实例。entrySet但是,每次新的迭代器前进时Map.Entry都会更新。

于 2008-09-05T21:26:57.117 回答
128

使用迭代器和泛型的示例:

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();
  // ...
}
于 2009-08-18T17:34:51.543 回答
107

这是一个两部分的问题:

如何迭代 Map 的条目- @ScArcher2完美地回答了这个问题。

迭代的顺序是什么- 如果您只是使用Map,那么严格来说,没有顺序保证。所以你不应该真正依赖任何实现给出的顺序。但是,该SortedMap接口扩展Map并提供了您正在寻找的内容 - 实现将提供一致的排序顺序。

NavigableMap是另一个有用的扩展- 这是一个SortedMap额外的方法,用于通过键集中的有序位置查找条目。因此,这可能会首先消除迭代的需要 - 您可能能够entry在使用higherEntrylowerEntryceilingEntryfloorEntry方法后找到您的具体情况。该descendingMap方法甚至为您提供了反转遍历顺序的显式方法。

于 2008-09-05T22:15:30.217 回答
87

有几种方法可以遍历 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

于 2014-02-05T06:42:55.377 回答
61

仅供参考,如果您只对地图的键/值而不是另一个感兴趣,您也可以map.keySet()使用map.values()

于 2008-09-05T22:27:52.510 回答
61

正确的方法是使用公认的答案,因为它是最有效的。我发现下面的代码看起来更干净一些。

for (String key: map.keySet()) {
   System.out.println(key + "/" + map.get(key));
}
于 2008-09-07T19:48:35.433 回答
54

使用Java 8,您可以使用 forEach 和 lambda 表达式迭代 Map,

map.forEach((k, v) -> System.out.println((k + ":" + v)));
于 2018-05-03T11:25:07.043 回答
44

使用Eclipse Collections,您将使用接口forEachKeyValue上的方法,该方法MapIterableMutableMapImmutableMap接口及其实现继承。

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 的提交者。

于 2012-12-18T23:13:13.537 回答
39

理论上,最有效的方式将取决于 Map 的实现。执行此操作的官方方法是调用map.entrySet(),它返回一组Map.Entry,每个都包含一个键和一个值(entry.getKey()entry.getValue())。

在一个特殊的实现中,无论您使用还是其他东西map.keySet(),它可能会有所不同。map.entrySet()但我想不出为什么有人会这样写。很可能它对你所做的事情没有任何影响。

是的,顺序将取决于实现 - 以及(可能)插入顺序和其他难以控制的因素。

[编辑] 我valueSet()最初写的,但当然entrySet()实际上是答案。

于 2008-09-05T21:18:00.137 回答
38

爪哇 8

我们有forEach接受lambda 表达式的方法。我们也有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()上面使用。

forEachOrderedforEach流相比? 不遵循遇到顺序(如果已forEach定义),并且本质上是非确定性的forEachOrdered。所以forEach不保证订单会被保留。另请检查内容以获取更多信息。

于 2015-09-02T01:00:00.393 回答
38

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 Expression的示例代码。这东西太酷了。一定要试。

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的更多信息,请访问此链接,并且必须阅读聚合操作,对于 Spliterator,请访问此链接

于 2015-10-06T15:07:33.627 回答
35

爪哇 8:

您可以使用 lambda 表达式:

myMap.entrySet().stream().forEach((entry) -> {
    Object currentKey = entry.getKey();
    Object currentValue = entry.getValue();
});

有关更多信息,请按照此操作

于 2014-08-04T10:30:49.377 回答
31

在 Map 中,可以迭代keys和/或values和/或both (e.g., entrySet) 取决于感兴趣的人_喜欢:

  1. 遍历keys -> keySet()地图:

     Map<String, Object> map = ...;
    
     for (String key : map.keySet()) {
         //your Business logic...
     }
    
  2. 遍历values -> values()地图:

     for (Object value : map.values()) {
         //your Business logic...
     }
    
  3. 遍历both -> entrySet()地图:

     for (Map.Entry<String, Object> entry : map.entrySet()) {
         String key = entry.getKey();
         Object value = entry.getValue();
         //your Business logic...
     }
    

此外,有 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);
}
于 2014-01-29T12:35:03.103 回答
30

用 Java 1.4 试试这个:

for( Iterator entries = myMap.entrySet().iterator(); entries.hasNext();){

  Entry entry = (Entry) entries.next();

  System.out.println(entry.getKey() + "/" + entry.getValue());

  //...
}
于 2010-02-03T06:10:03.310 回答
27

排序将始终取决于特定的地图实现。使用 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,
于 2016-10-26T10:56:58.117 回答
25

Java 8 最紧凑:

map.entrySet().forEach(System.out::println);
于 2018-04-19T12:32:20.627 回答
23

如果我有一个在 Java 中实现 Map 接口的对象,并且我希望遍历其中包含的每一对,那么遍历映射的最有效方法是什么?

如果循环键的效率是您的应用程序的优先事项,那么选择一个Map以您想要的顺序维护键的实现。

元素的顺序是否取决于我对接口的特定地图实现?

是的,一点没错。

  • 一些Map实现承诺一定的迭代顺序,而另一些则没有。
  • 不同的实现Map保持键值对的不同顺序。

请参阅我创建的此表,该表总结了Map与 Java 11 捆绑的各种实现。具体来说,请注意迭代顺序列。单击/点击以缩放。

Java 11 中的地图实现表,比较它们的特性

您可以看到有四个Map实现维护顺序

  • TreeMap
  • ConcurrentSkipListMap
  • LinkedHashMap
  • EnumMap

NavigableMap界面

其中两个实现了NavigableMap接口:TreeMap& ConcurrentSkipListMap

较旧的SortedMap界面被较新的NavigableMap界面有效地取代。但是您可能会发现仅实现旧接口的第 3 方实现。

自然秩序

如果您想要 aMap保持其对按密钥的“自然顺序”排列,请使用TreeMapor ConcurrentSkipListMap。术语“自然顺序”是指键实现的类Comparable。该compareTo方法返回的值用于排序中的比较。

定制订单

如果要为要用于维护排序顺序的键指定自定义排序例程,请传递Comparator适合于键类的实现。使用TreeMap或者ConcurrentSkipListMap,传递你的Comparator.

原始广告订单

如果您希望成对的地图保持在您将它们插入地图时的原始顺序,请使用LinkedHashMap.

枚举定义顺序

如果您使用枚举(例如DayOfWeekMonth作为键),请使用EnumMap该类。这个类不仅高度优化以使用非常少的内存并且运行速度非常快,而且它按照枚举定义的顺序维护您的配对。例如DayOfWeekDayOfWeek.MONDAY迭代时首先找到的键,DayOfWeek.SUNDAY最后找到的键。

其他注意事项

在选择Map实现时,还要考虑:

  • 空值。一些实现禁止/接受 NULL 作为键和/或值。
  • 并发。如果要跨线程操作映射,则必须使用支持并发的实现。Collections::synchronizedMap或者用(不太可取)包裹地图。

这两个考虑因素都包含在上面的图表中。

于 2019-10-26T19:44:57.650 回答
22

如果您有一个通用的无类型地图,您可以使用:

Map map = new HashMap();
for (Map.Entry entry : ((Set<Map.Entry>) map.entrySet())) {
    System.out.println(entry.getKey() + "/" + entry.getValue());
}
于 2013-11-29T12:53:43.087 回答
21
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();
        }
    }
}
于 2012-05-17T09:21:56.997 回答
17
    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());    
    }
于 2014-03-19T17:34:52.137 回答
14

您可以使用泛型来做到这一点:

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());
}
于 2013-07-01T12:54:20.120 回答
14

使用 Java 8:

map.entrySet().forEach(entry -> System.out.println(entry.getValue()));
于 2018-04-17T18:46:05.107 回答
14

一个有效的 Map 迭代解决方案是for从 Java 5 到 Java 7 的循环。这里是:

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");
    }
});
于 2018-11-27T10:24:47.960 回答
13
           //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();

            }
于 2016-04-13T07:47:46.873 回答
11

迭代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);
}
于 2017-11-05T14:18:17.527 回答
11

有很多方法可以做到这一点。下面是几个简单的步骤:

假设你有一张像这样的地图:

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));
}
于 2017-11-13T03:52:15.710 回答
10

是的,正如许多人同意的那样,这是迭代Map.

nullpointerexception但是如果地图是有机会抛出null。不要忘记输入null.check in。

                                                 |
                                                 |
                                         - - - -
                                       |
                                       |
for (Map.Entry<String, Object> entry : map.entrySet()) {
    String key = entry.getKey();
    Object value = entry.getValue();
}
于 2013-03-21T19:33:26.500 回答
9
package com.test;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class Test {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("ram", "ayodhya");
        map.put("krishan", "mathura");
        map.put("shiv", "kailash");

        System.out.println("********* Keys *********");
        Set<String> keys = map.keySet();
        for (String key : keys) {
            System.out.println(key);
        }

        System.out.println("********* Values *********");
        Collection<String> values = map.values();
        for (String value : values) {
            System.out.println(value);
        }

        System.out.println("***** Keys and Values (Using for each loop) *****");
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println("Key: " + entry.getKey() + "\t Value: "
                    + entry.getValue());
        }

        System.out.println("***** Keys and Values (Using while loop) *****");
        Iterator<Entry<String, String>> entries = map.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) entries
                    .next();
            System.out.println("Key: " + entry.getKey() + "\t Value: "
                    + entry.getValue());
        }

        System.out
                .println("** Keys and Values (Using java 8 using lambdas )***");
        map.forEach((k, v) -> System.out
                .println("Key: " + k + "\t value: " + v));
    }
}
于 2017-04-06T06:36:15.083 回答
8

Map.forEach

简单地使用Map::forEachkey 和 value 都传递给你的地方BiConsumer怎么样?

map.forEach((k,v)->{
    System.out.println(k+"->"+v);
});
于 2020-01-06T07:44:06.120 回答
7

这是一个通用的类型安全方法,可以调用它来转储任何给定Map的 .

import java.util.Iterator;
import java.util.Map;

public class MapUtils {
    static interface ItemCallback<K, V> {
        void handler(K key, V value, Map<K, V> map);
    }

    public static <K, V> void forEach(Map<K, V> map, ItemCallback<K, V> callback) {
        Iterator<Map.Entry<K, V>> it = map.entrySet().iterator();

        while (it.hasNext()) {
            Map.Entry<K, V> entry = it.next();

            callback.handler(entry.getKey(), entry.getValue(), map);
        }
    }

    public static <K, V> void printMap(Map<K, V> map) {
        forEach(map, new ItemCallback<K, V>() {
            @Override
            public void handler(K key, V value, Map<K, V> map) {
                System.out.println(key + " = " + value);
            }
        });
    }
}

例子

这是它的使用示例。请注意,Map方法的类型是推断的。

import java.util.*;

public class MapPrinter {
    public static void main(String[] args) {
        List<Map<?, ?>> maps = new ArrayList<Map<?, ?>>() {
            private static final long serialVersionUID = 1L;
            {
                add(new LinkedHashMap<String, Integer>() {
                    private static final long serialVersionUID = 1L;
                    {
                        put("One", 0);
                        put("Two", 1);
                        put("Three", 3);
                    }
                });

                add(new LinkedHashMap<String, Object>() {
                    private static final long serialVersionUID = 1L;
                    {
                        put("Object", new Object());
                        put("Integer", new Integer(0));
                        put("Double", new Double(0.0));
                    }
                });
            }
        };

        for (Map<?, ?> map : maps) {
            MapUtils.printMap(map);
            System.out.println();
        }
    }
}

输出

One = 0
Two = 1
Three = 3

Object = java.lang.Object@15db9742
Integer = 0
Double = 0.0
于 2015-05-13T12:37:32.730 回答
7

从 Java 10 开始,您可以使用局部变量推断(又名“var”)来使许多已经可用的答案不那么臃肿。例如:

for (var entry : map.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}
于 2020-06-14T21:19:22.587 回答
7

这些都是迭代HashMap的所有可能方式。

HashMap<Integer,String> map=new HashMap<Integer,String>();
    map.put(1,"David");  //Adding elements in Map
    map.put(2,"John");
    map.put(4,"Samyuktha");
    map.put(3,"jasmin");
    System.out.println("Iterating Hashmap...");

    //way 1 (java 8 Method)
    map.forEach((key, value) -> {
        System.out.println(key+" : "+ value);
    });

    //way 2 (java 7 Method)
    for(Map.Entry me : map.entrySet()){
        System.out.println(me.getKey()+" "+me.getValue());
    }

    //way 3 (Legacy type to iterate HashMap)
    Iterator iterator = map.entrySet().iterator();//map.keySet().iterator()
    while (iterator.hasNext())
    {
        Map.Entry me =(Map.Entry)iterator.next();
        System.out.println(me.getKey()+" : "+ me.getValue());
    }
    
}
于 2021-09-29T15:35:17.910 回答
6

有几种方法可以迭代地图。请参考以下代码。

当您使用迭代器接口迭代地图时,您必须使用Entry<K,V>or entrySet()

它看起来像这样:

    import java.util.*;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;

    public class IteratMapDemo{

        public static void main(String arg[]){
            Map<String, String> mapOne = new HashMap<String, String>();
            mapOne.put("1", "January");
            mapOne.put("2", "February");
            mapOne.put("3", "March");
            mapOne.put("4", "April");
            mapOne.put("5", "May");
            mapOne.put("6", "June");
            mapOne.put("7", "July");
            mapOne.put("8", "August");
            mapOne.put("9", "September");
            mapOne.put("10", "Octomber");
            mapOne.put("11", "November");
            mapOne.put("12", "December");

            Iterator it = mapOne.entrySet().iterator();
            while(it.hasNext())
            {
                Map.Entry me = (Map.Entry) it.next();
                //System.out.println("Get Key through While loop = " + me.getKey());
            }
            for(Map.Entry<String, String> entry:mapOne.entrySet()){
                //System.out.println(entry.getKey() + "=" + entry.getValue());
            }

            for (Object key : mapOne.keySet()) {
                System.out.println("Key: " + key.toString() + " Value: " +
                                   mapOne.get(key));
            }
        }
    }
于 2014-01-03T12:28:28.677 回答
6

如果您遍历Map, 的原因是对值进行操作并写入结果Map。我建议在Google Guava类中使用transform-methods 。 Maps

import com.google.common.collect.Maps;

将 添加Maps到导入后,您可以在地图上使用Maps.transformValuesMaps.transformEntries,如下所示:

public void transformMap(){
    Map<String, Integer> map = new HashMap<>();
    map.put("a", 2);
    map.put("b", 4);

    Map<String, Integer> result = Maps.transformValues(map, num -> num * 2);
    result.forEach((key, val) -> print(key, Integer.toString(val)));
    // key=a,value=4
    // key=b,value=8

    Map<String, String> result2 = Maps.transformEntries(map, (key, value) -> value + "[" + key + "]");
    result2.forEach(this::print);
    // key=a,value=2[a]
    // key=b,value=4[b]
}

private void print(String key, String val){
    System.out.println("key=" + key + ",value=" + val);
}
于 2015-08-29T17:11:44.870 回答
6

我喜欢连接一个计数器,然后保存计数器的最终值;

int counter = 0;
HashMap<String, String> m = new HashMap<String, String>();
for(int i = 0;i<items.length;i++)
{
m.put("firstname"+i, items.get(i).getFirstName());
counter = i;
}

m.put("recordCount",String.valueOf(counter));

然后当你想检索时:

int recordCount = Integer.parseInf(m.get("recordCount"));
for(int i =0 ;i<recordCount;i++)
{
System.out.println("First Name :" + m.get("firstname"+i));
}
于 2019-06-05T19:56:47.233 回答
6

使用 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));
于 2019-08-02T07:30:38.323 回答
3

它并不能完全回答 OP 的问题,但可能对找到此页面的其他人有用:

如果您只需要值而不需要键,则可以这样做:

Map<Ktype, Vtype> myMap = [...];
for (Vtype v: myMap.values()) {
  System.out.println("value: " + v);
}

Ktype,Vtype是伪代码。

于 2015-01-10T00:22:38.537 回答
3

如果您想按照添加元素的顺序遍历地图,请使用LinkedHashMap而不是 just Map

这种方法过去对我有用:

LinkedHashMap<String,Integer> test=new LinkedHashMap();

test.put("foo",69);
test.put("bar",1337);

for(int i=0;i<test.size();i++){
    System.out.println(test.get(test.keySet().toArray()[i]));
}

输出:

69
1337
于 2015-10-27T18:09:34.713 回答
3
Map<String, String> map = 
for (Map.Entry<String, String> entry : map.entrySet()) {
    MapKey = entry.getKey() 
    MapValue = entry.getValue();
}
于 2020-09-15T22:53:49.317 回答
3

您可以搜索键,并在键的帮助下找到映射的关联值,因为映射具有唯一键,看看当键在此处此处重复时会发生什么。

演示图:

 Map<String, String> map = new HashMap();
  map.put("name", "Name");
  map.put("age", "23");
  map.put("address", "NP");
  map.put("faculty", "BE");
  map.put("major", "CS");
  map.put("head", "MDK");
 

要仅获取密钥,您可以map.keySet();像这样使用:

for(String key : map.keySet()) {
      System.out.println(key);
  }

要仅获取价值,您可以map.values();像这样使用:

      for(String value : map.values()) {
      System.out.println(value);
  }

要同时获取键及其值,您仍然可以使用map.keySet();并获取其对应的值,如下所示:

 //this prints the key value pair
  for (String k : map.keySet()) {
        System.out.println(k + " " + map.get(k) + " ");
    }

map.get(key)给出该键指向的值。

于 2021-01-11T16:04:27.647 回答
2

我使用以下代码将地图的数据复制到另一个:

HashMap product =(HashMap)shopping_truck.get(i);
HashMap tmp = new HashMap();
for (Iterator it = product.entrySet().iterator(); it.hasNext();) {
    Map.Entry thisEntry = (Map.Entry) it.next();
    tmp.put(thisEntry.getKey(), thisEntry.getValue());
}
于 2014-08-21T22:15:17.823 回答
2

我相信这是最简单的方法......

/* For example, this could be a map object */
Map<String, Integer> MAP = new Map<>();

// Do something like put keys/value pairs into the map, etc...
MAP.put("Denver", 35);
MAP.put("Patriots", 14);

/* Then, simply use a for each loop like this to iterate */
for (Object o : MAP.entrySet()) {
    Map.Entry pair = (Map.Entry) o;
    // Do whatever with the pair here (i.e. pair.getKey(), or pair.getValue();
}
于 2015-05-30T19:08:04.683 回答