“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。
更有趣的是 - 这仅对调试有帮助 - 因为您不能覆盖 hashCode
或 equals
或 toString
lambda 表达式——所以除了了解某些事情是如何工作的——这些信息是非常无用的。
关于java - 为什么? java lambda 表达式(没有外部引用变量)在循环中具有相同的哈希码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45450196/