forEach 循环 Java 8 for Map entry set

2022-08-31 11:12:54

我试图将每个循环的旧约定转换为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

读取 javadoc:期望一个 as 参数,抽象方法的签名是 。Map<K, V>.forEach()BiConsumer<? super K,? super V>BiConsumer<T, U>accept(T t, U u)

因此,您应该向它传递一个 lambda 表达式,该表达式将两个输入作为参数:键和值:

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

如果您在映射的条目集上调用 forEach(),而不是在映射本身上调用 forEach(),则代码将起作用:

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

答案 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() - from 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.forEach()而不是map.entrySet().forEach()有任何性能优势。因此,就您而言,答案实际上取决于您的个人品味:)

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


推荐