java - 为什么? java lambda 表达式(没有外部引用变量)在循环中具有相同的哈希码

标签 java java-8

“for 循环”或“streams foreach”中的 lambda 表达式具有相同的哈希码。 为什么?

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Main {

public static void main(String[] args) {

    List<String> list = Arrays.asList("Mukesh", "Vishal", "Amar" ,"Ansony");


    list.stream().collect(Collectors.groupingBy(

            new Function<String, Consumer<List<String>>>() {

                Map<String, Consumer<List<String>>> map = new HashMap<String, Consumer<List<String>>>();

                @Override
                public Consumer<List<String>> apply(String t) {

                    String key = t.substring(0,1);
                    Consumer<List<String>> cs = map.get(key);
                    if(cs == null) {

                        cs = (list) -> {
                            System.out.println("------start");
                            list.forEach(it -> {
                                System.out.println(it);
                            });
                            System.out.println("------end");
                        };

                        map.put(key, cs);
                        }

                        System.out.println("group key Consumer hashcode : "+ cs.hashCode());

                        return cs;
                    }

                }

                ))
        .entrySet()
        .forEach( entry -> {


            System.out.println("key : " + entry.getKey());
            System.out.println("value : " + entry.getValue());

            entry.getKey().accept(entry.getValue());
        });
    }

}

在其他情况下; 我在 lambda 表达式主体 block 中添加了外部引用变量代码;

像这样->

                            cs = (list) -> {
                            t.hashCode(); // <---- !!!
                            System.out.println("------start");
                            list.forEach(it -> {
                                System.out.println(it);
                            });
                            System.out.println("------end");
                        };

此代码打印不同的哈希码..

(ㅜ..ㅜ)

最佳答案

您的问题似乎是为什么第一种情况(没有t.hashCode)的hashCode 是相同的,以及为什么当您添加t.hashCode 时它是不同的。

@holi-java 为您指明了正确的方向 - 第一个称为 stateless lambda - 因此在当前实现下你将始终获得一个单例 - 的相同实例Consumer 将被重新用于所有调用。

一旦你让它成为有状态的(通过添加一个外部变量——在你的例子中是 t.hashCode)——你只是让它成为一个有状态的 lambda——在当前的实现下你会得到一个 消费者的新实例每次 - 因此您输出不同的 hashCode。

更有趣的是 - 这仅对调试有帮助 - 因为您不能覆盖 hashCodeequalstoString lambda 表达式——所以除了了解某些事情是如何工作的——这些信息是非常无用的。

关于java - 为什么? java lambda 表达式(没有外部引用变量)在循环中具有相同的哈希码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45450196/

相关文章:

java - 单击 <li> 列表项不使用 Selenium Java

Java:如何处理我的应用程序插件中的自定义设置?

java - 如何将以下java代码转换为java 8?

Java 正则表达式 : Selecting balanced bracket data

java - 是否有 java 11 native 方法将 json 转换为对象?

Java:将电子邮件发送到非 ASCII 电子邮件地址

java - Java 8 中抽象类对接口(interface)的偏好

java - 为什么Java工作窃取池(ForkJoinPool)不支持从线程池中预创建线程?

java - 泛型友好的类型处理程序映射

java - 如何将流与干扰方法和构造函数一起使用,为什么不使用 .peek()?