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

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


当前回答

Map上的一个有效迭代解决方案是从Java5到Java7的for循环。这里是:

for (String key : phnMap.keySet()) {
    System.out.println("Key: " + key + " Value: " + phnMap.get(key));
}

在Java8中,可以使用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");
    }
});

其他回答

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

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

Java 8:

可以使用lambda表达式:

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

有关详细信息,请遵循以下步骤。

排序将始终取决于特定的映射实现。使用Java 8,您可以使用以下任一选项:

map.forEach((k,v) -> { System.out.println(k + ":" + v); });

Or:

map.entrySet().forEach((e) -> {
            System.out.println(e.getKey() + " : " + e.getValue());
        });

结果相同(顺序相同)。entrySet由地图支持,因此您可以获得相同的顺序。第二个很方便,因为它允许您使用lambdas,例如,如果您只想打印大于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,

是的,顺序取决于特定的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();
  // ...
}