Java mapToLong不使用';后的过滤器非空;行不通
我的密码是这样的Java mapToLong不使用';后的过滤器非空;行不通,java,lambda,filter,Java,Lambda,Filter,我的密码是这样的 class A { private Long b; public Long getB() { return b; } public void setB(Long b) { this.b = b; } public static void main(String[] args) { A a1 = new A(); List<A> list = new
class A {
private Long b;
public Long getB() {
return b;
}
public void setB(Long b) {
this.b = b;
}
public static void main(String[] args) {
A a1 = new A();
List<A> list = new ArrayList<>();
list.add(a1);
list.stream().mapToLong(A::getB).filter(Objects::nonNull).sum();
}
}
它工作得很好。我想知道原因。
mapToLong
将Long
转换为Long
——如果null
,您确实会得到一个异常
在转换之前,您需要过滤null
s:
list.stream()
.map(A::getB)
.filter(Objects::nonNull) //filter the nulls first
.mapToLong(Long::longValue) //then convert to primitive
.sum();
将
tolong函数
传递给mapToLong
函数,这是它的签名
long applyAsLong(T value);
传递方法引用A::getB
——这里,它接受b
,并通过取消装箱返回它(从Long
转换为primitiveLong
)。因为它是空的,所以会导致NPE
通过更早地进行过滤,可以避免这种情况的发生
请参见:此处
list.stream().mapToLong(A::getB).filter(Objects::nonNull).sum();
您正在尝试将列表中的每一个B转换为Long,然后不过滤空值。现在您正在尝试转换空值,因为您尚未筛选空值。这会引发NullPointerException
这里
您不过滤空值,然后映射并将其转换为长值。当您尝试转换时,这里没有空值,因为您已经过滤了它们,所以也没有空值异常。为什么此代码失败
list.stream().mapToLong(A::getB).filter(Objects::nonNull).sum();
因为流操作是按顺序执行的。因此,如果流A::getB
的任何元素没有返回NOTNULLLong
,则在收集过程中会引发异常
为什么成功
list.stream().filter(a -> a.getB()!=null).mapToLong(A::getB).sum();
因为第一次执行的filter()
会删除导致a::getB
操作的空元素。
因此,在收集流中只添加NOTNULL元素。所以也不例外。
但问题是您执行了两次映射a::getB
。即使在这里它并不昂贵(只是一种消遣),但它仍然是如此的无助。你想要的是:
list.stream()
.map(A::getB) // return Stream<Long> that may contain null
.filter(Objects::nonNull) // filter null elements
.mapToLong(s->s) // map Long to long
.sum(); // sum
list.stream()
.map(A::getB)//返回可能包含null的流
.filter(Objects::nonNull)//筛选空元素
.mapToLong(s->s)//从长到长映射
.sum();//总和
事实上,我认为它不能满足OP要求。如果比较工作和不工作示例,我们猜测null
来自原始列表中的A::getB
映射,而不是null A
元素。
list.stream().filter(a -> a.getB()!=null).mapToLong(A::getB).sum();
list.stream()
.map(A::getB) // return Stream<Long> that may contain null
.filter(Objects::nonNull) // filter null elements
.mapToLong(s->s) // map Long to long
.sum(); // sum