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

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


当前回答

这些都是迭代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 way 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());
    }
    
}

其他回答

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());
}

对于Eclipse集合,您将在MapIterable接口上使用forEachKeyValue方法,该方法由MutableMap和ImmutableMap接口及其实现继承。

MutableMap<Integer, String> map = 
    Maps.mutable.of(1, "One", 2, "Two", 3, "Three");

MutableBag<String> result = Bags.mutable.empty();
map.forEachKeyValue((key, value) -> result.add(key + value));

MutableBag<String> expected = Bags.mutable.of("1One", "2Two", "3Three");
Assertions.assertEquals(expected, result);

将forEachKeyValue与EclipseCollections(EC)Map实现一起使用比使用entrySet更有效的原因是因为EC Map实现不存储Map.Entry对象。将entrySet与EC Map实现一起使用会动态生成Map.Entry对象。forEachKeyValue方法能够避免创建Map.Entry对象,因为它可以直接导航Map实现的内部结构。在这种情况下,使用内部迭代器比使用外部迭代器有好处。

注意:我是Eclipse集合的提交人。

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

在特殊的实现中,使用map.keySet()、map.entrySet()或其他方法可能会有所不同。但我想不出为什么有人会这样写。最有可能的是,你所做的对绩效没有影响。

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

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

如果要按元素添加的顺序遍历映射,请使用LinkedHashMap,而不是仅使用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

这些都是迭代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 way 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());
    }
    
}