为什么这个lambda表达式在语句中不起作用,但在方法中工作?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么这个lambda表达式在语句中不起作用,但在方法中工作?相关的知识,希望对你有一定的参考价值。
我想要的建议是通过某个内部对象的字段过滤列表。因此我在互联网上找到一种方法,如下所示:
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
那么,我这样用
list.stream().filter(LambdaUtils.distinctByKey(o -> o.getLogisticsNumber() == null ? o.getId() : o.getLogisticsNumber())).collect(Collectors.toList());
它工作正常,但我想尝试不同的东西,所以我改变代码不使用函数,而不是代码。像这样:
list.stream().filter(
x -> {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
Function<DeliveryOrderItemMaterialLogisticInfo ,Object> keyExtractor = o -> o.getLogisticsNumber() == null ? o.getId() : o.getLogisticsNumber();
return seen.putIfAbsent(keyExtractor.apply(x), Boolean.TRUE) == null;
}
).collect(Collectors.toList());
那么结果就是错误。
为什么?这两者有什么不同?
答案
在您的第二个代码版本中:
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
地图Map<> seen
是为每个元素x
初始化的,因此你的过滤器总是返回true
,这将让所有元素直通。
将Map<> seen
声明移动到lambda外部将更正您的使用情况。
在第一个代码版本中,Map<> seen
仅初始化为一个。它返回的只是一个谓词:
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
当您将此谓词传递给流时,它不会创建新的Map
,而是使用之前声明的引用Map<> seen
。
以上是关于为什么这个lambda表达式在语句中不起作用,但在方法中工作?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在未计算的操作数中不允许使用 lambda 表达式,但在常量表达式的未计算部分中允许使用 lambda 表达式?
基本的 If else 语句在 javascript 中不起作用
Boost union 在 1.67 中不起作用,但在 1.61 中起作用。为啥?