forEach 循环 Java 8 for Map 条目集

Posted

技术标签:

【中文标题】forEach 循环 Java 8 for Map 条目集【英文标题】:forEach loop Java 8 for Map entry set 【发布时间】:2015-11-22 17:52:30 【问题描述】:

我正在尝试将每个循环的旧常规转换为 java7 到 java8 的映射条目集的每个循环,但我遇到了错误。 这是我要转换的代码:

for (Map.Entry<String, String> entry : map.entrySet()) 
        System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
    

这是我所做的更改:

map.forEach( Map.Entry<String, String> entry -> 
       System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());

   ); 

我也试过这样做:

Map.Entry<String, String> entry;
   map.forEach(entry -> 
       System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());

   );

但仍然面临错误。我得到的错误是: Lambda 表达式的签名与函数式接口方​​法accept(String, String)的签名不匹配

【问题讨论】:

【参考方案1】:

读取the javadoc:Map&lt;K, V&gt;.forEach() 需要BiConsumer&lt;? super K,? super V&gt; 作为参数,BiConsumer&lt;T, U&gt; 抽象方法的签名是accept(T t, U u)

所以你应该传递一个 lambda 表达式,它接受两个输入作为参数:键和值:

map.forEach((key, value) -> 
    System.out.println("Key : " + key + " Value : " + value);
);

如果您在地图的入口集而不是地图本身上调用 forEach(),您的代码将起作用:

map.entrySet().forEach(entry -> 
    System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
); 

【讨论】:

太棒了。现在两者都工作。但是哪一个是更好的方法?在什么情况下性能会更好? @JBNizet 第二个版本强制为每个条目创建一个Map.Entry实例;第一个为您提供没有实例化的键和值。因此Map.Entry 是一个中间人,您可以使用第一个版本来避免这种情况。 @Marko Topolnik:对于大多数Map 实现,Map.Entry 实例在迭代之前已经存在,不需要创建。尽管如此,在操作中不必处理 Map.Entry 是可读性的胜利,并且由于不需要额外的方法调用来检索键和值,因此具有更好的性能的微小潜力。 @Holger 我会强调你的默认含义:对于大多数,但不是全部Map 实现是正确的,ConcurrentHashMap 是一个重要的反例。跨度> @Marko Topolnik:但是当迭代整个ConcurrentHashMap 时,临时条目实例是最后需要担心的事情。尽管如此,我们还是同意首选map.forEach((key, value) -&gt; …);...【参考方案2】:

也许是回答“哪个版本更快,我应该使用哪个版本?”之类的问题的最佳方式。就是看源码:

map.forEach() - 来自 Map.java

default void forEach(BiConsumer<? super K, ? super V> action) 
    Objects.requireNonNull(action);
    for (Map.Entry<K, V> entry : entrySet()) 
        K k;
        V v;
        try 
            k = entry.getKey();
            v = entry.getValue();
         catch(IllegalStateException ise) 
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        
        action.accept(k, v);
    

javadoc

map.entrySet().forEach() - 来自 Iterable.java

default void forEach(Consumer<? super T> action) 
    Objects.requireNonNull(action);
    for (T t : this) 
        action.accept(t);
    

javadoc

这立即表明 map.forEach() 也在内部使用 Map.Entry。所以我不希望在 map.entrySet().forEach() 上使用 map.forEach() 有任何性能优势。所以在你的情况下,答案真的取决于你的个人品味:)

有关差异的完整列表,请参阅提供的 javadoc 链接。快乐编码!

【讨论】:

【参考方案3】:

您可以根据需要使用以下代码

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

【讨论】:

此答案与 JB Nizet 2 年前提供的答案的部分相同,并且没有提供额外的有用信息。【参考方案4】:

下面是树的最佳方法 1.用入口集迭代

for (Map.Entry<String, Integer> entry : map.entrySet()) 
    System.out.println(entry.getKey() + ":" + entry.getValue());

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

3 流 map.entrySet().stream() .forEach(e -> System.out.println(e.getKey() + ":" + e.getValue()));

【讨论】:

【参考方案5】:
String ss = "Pawan kavita kiyansh Patidar Patidar";
    StringBuilder ress = new StringBuilder();
    
    Map<Character, Integer> fre = ss.chars().boxed()
            .collect(Collectors.toMap(k->Character.valueOf((char) k.intValue()),k->1,Integer::sum));
    
      //fre.forEach((k, v) -> System.out.println((k + ":" + v)));
    
    fre.entrySet().forEach(e ->
            //System.out.println(e.getKey() + ":" + e.getValue());
            //ress.append(String.valueOf(e.getKey())+e.getValue());
        ); 

    fre.forEach((k,v)->
        //System.out.println("Item : " + k + " Count : " + v);
        ress.append(String.valueOf(k)+String.valueOf(v));
    );
    
    System.out.println(ress.toString());

【讨论】:

虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。【参考方案6】:
HashMap<String,Integer> hm = new HashMap();

 hm.put("A",1);
 hm.put("B",2);
 hm.put("C",3);
 hm.put("D",4);

 hm.forEach((key,value)->
     System.out.println("Key: "+key + " value: "+value);
 );

【讨论】:

请为您的答案添加一些解释。这将帮助其他人根据自己的需要调整您的答案。 From Review.【参考方案7】:

流 API

public void iterateStreamAPI(Map<String, Integer> map) 
    map.entrySet().stream().forEach(e -> System.out.println(e.getKey() + ":"e.getValue()));

【讨论】:

以上是关于forEach 循环 Java 8 for Map 条目集的主要内容,如果未能解决你的问题,请参考以下文章

java中foreach括号中写的是啥

Array数组循环全解1

java map 用for循环的问题

Java的for循环、增强for循环、lambda表达式中的forEach 三种方式优缺点比较?

for循环,foreach, map,reduce用法对比+for in,for of

C++ 中map中是数怎么经过for循环提取出来,