valueset - map iterator 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


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

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

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

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


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

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

使用Java 8

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

使用Java 8:

map.entrySet().forEach(entry -> System.out.println(entry.getValue()));

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

尝试使用Java 1.4:

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

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

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

  //...
}

排序将始终取决于具体的地图实施。 使用Java 8,您可以使用以下任一方法:

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

要么:

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的最佳方式。

但是如果map是null则有机会抛出nullpointerexception 。 不要忘记将null .check放入。

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

最紧凑的Java 8:

map.entrySet().forEach(System.out::println);

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

假设您有一个地图,如:

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

这是一个两部分问题:

如何迭代Map的条目 - @ ScArcher2已经完美地answered这个问题。

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

NavigableMap是另一个有用的扩展 - 这是一个SortedMap其中包含其他方法,用于按键集中的有序位置查找条目。 因此,这可能会消除首先进行迭代的需要 - 您可能能够在使用higherEntrylowerEntryceilingEntryfloorEntry方法之后找到您所使用的特定entrydescendingMap方法甚至为您提供了一种反转遍历顺序的显式方法。


迭代地图有几种方法。

这里是通过在地图中存储一百万个键值对来比较它们在地图中存储的公共数据集的性能,并将迭代在地图上。

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


           //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