print - map traverse java




如何有效地迭代Java Map中的每個條目? (20)

Lambda Expression Java 8

在Java 1.8(Java 8)中,通過使用類似於來自Iterable Interface的迭代器的聚合操作( 流操作 )的forEach方法,這變得更加容易。

只需將下面的語句粘貼到代碼中,然後將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();

UPDATE

包括Oracle Docs的文檔鏈接。 有關Lambda的更多信息,請轉到此link並且必須閱讀Aggregate Operations ,對於Spliterator,請轉到此link

如果我有一個用Java實現Map接口的對象,並希望迭代其中包含的每一對,那麼通過地圖的最有效方法是什麼?

元素的排序是否取決於我對界面的具體映射實現?


Java 8:

您可以使用lambda表達式:

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

有關更多信息,請按照this


使用Eclipse Collections (以前稱為GS Collections ),您可以在MapIterable接口上使用forEachKeyValue方法,該方法由MutableMap和ImmutableMap接口及其實現繼承。

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

使用Java 8 lambda語法,您可以按如下方式編寫代碼:

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

注意:我是Eclipse Collections的提交者。


使用Java 8

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

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

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

僅供參考,如果您只對地圖的鍵/值感興趣而不感興趣,則還可以使用map.keySet()map.values()


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

kv的類型將由編譯器推斷,不再需要使用Map.Entry

十分簡單!


在Java 8中,我們有forEach方法接受link 。 我們還有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()


如果您有一個通用的無類型地圖,您可以使用:

Map map = new HashMap();
for (Map.Entry entry : ((Set<Map.Entry>) map.entrySet())) {
    System.out.println(entry.getKey() + "/" + entry.getValue());
}

從理論上講,最有效的方法取決於Map的實現。 執行此操作的官方方法是調用map.entrySet() ,它返回一組Map.Entry ,每個Map.Entry包含一個鍵和一個值( entry.getKey()entry.getValue() )。

在一個特殊的實現中,無論是使用map.keySet()map.entrySet()還是其他東西,它都可能會有所不同。 但我想不出有人會這樣寫的原因。 很可能它對你的表現沒有任何影響。

是的,訂單將取決於實施 - 以及(可能)插入順序和其他難以控制的因素。

[編輯]我最初寫了valueSet()但當然entrySet()實際上是答案。


是的,因為很多人都認為這是迭代Map的最佳方式。

但是如果map是null則有機會拋出nullpointerexception 。 不要忘記將null .check放入。

                                                 |
                                                 |
                                         - - - -
                                       |
                                       |
for (Map.Entry<String, Object> entry : map.entrySet()) {
    String key = entry.getKey();
    Object value = entry.getValue();
}

是的,訂單取決於具體的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();
  // ...
}

有很多方法可以做到這一點。 以下是幾個簡單的步驟:

假設您有一個地圖,如:

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

正確的方法是使用接受的答案,因為它是最有效的。 我發現以下代碼看起來更清晰。

for (String key: map.keySet()) {
   System.out.println(key + "/" + map.get(key));
}

迭代地圖有幾種方法。

這裡是通過在地圖中存儲一百萬個鍵值對來比較它們在地圖中存儲的公共數據集的性能,並將迭代在地圖上。

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<String,Thing> map = ...;
for (Map.Entry<String,Thing> entry : map.entrySet()) {
    String key = entry.getKey();
    Thing thing = entry.getValue();
    ...
}

HashMap是規範的地圖實現,不提供保證(或者如果不對其執行變異操作則不應更改順序)。 SortedMap將根據鍵的自然順序或Comparator (如果提供)返回條目。 LinkedHashMap將以插入順序或訪問順序返回條目,具體取決於它的構造方式。 EnumMap按鍵的自然順序返回條目。

(更新:我認為這不再是真的。 )注意, IdentityHashMap entrySet迭代器當前有一個特殊的實現,它為entrySet每個項返回相同的Map.Entry實例! 但是,每當新的迭代器推進時, Map.Entry都會更新。


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

            }

    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<String, String> map = ...
for (Map.Entry<String, String> entry : map.entrySet())
{
    System.out.println(entry.getKey() + "/" + entry.getValue());
}

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




iteration