如果我有一个用Java实现Map接口的对象,并且我希望对其中包含的每一对进行迭代,那么最有效的方法是什么?

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


当前回答

这是一个由两部分组成的问题:

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

迭代的顺序是什么?如果您只是使用Map,那么严格来说,没有排序保证。因此,您不应该真正依赖任何实现给出的顺序。然而,SortedMap接口扩展了Map并提供了您所需要的内容——实现将始终提供一致的排序顺序。

NavigableMap是另一个有用的扩展-这是一个SortedMap,它提供了其他方法,用于根据条目在键集中的顺序位置查找条目。因此,这可能会从一开始就消除迭代的需要——在使用higherEntry、lowerEntry、ceilingEntry或floorEntry方法后,您可能能够找到所需的特定条目。descendingMap方法甚至为您提供了一种反转遍历顺序的显式方法。

其他回答

在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。

小菜一碟

为了总结其他答案并将它们与我所知道的结合起来,我找到了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上。

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

演示地图:

 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) + " ");
    }

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

迭代地图非常简单。

for(Object key: map.keySet()){
   Object value= map.get(key);
   //Do your stuff
}

例如,您有一个Map<String,int>数据;

for(Object key: data.keySet()){
  int value= data.get(key);
}
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));
    }
}