我的代码是这样
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();
}
}
我想过滤null,但是它不起作用,并给我NullPointerException。
如果我在mapToLong之前进行过滤,例如
list.stream().filter(a -> a.getB()!=null).mapToLong(A::getB).sum();
效果很好。我想知道为什么。
答案 0 :(得分:4)
mapToLong
将Long
转换为long
-如果是null
,则确实会出现异常。
您需要过滤null
转换前的 :
list.stream()
.map(A::getB)
.filter(Objects::nonNull) //filter the nulls first
.mapToLong(Long::longValue) //then convert to primitive
.sum();
答案 1 :(得分:2)
您将m = df['A'].notna()
c = m.cumsum()
def f(x):
lens = len(x.index)
a = np.arange(lens)
return a // (lens / 2) == 0
mask = c[~m].groupby(c).transform(f)
#should be removed
#mask = mask.reindex(df.index, fill_value=False)
df['B'] = df['A'].where(mask, df['A'].bfill()).ffill().bfill()
print (df)
A B
0 NaN 4.0
1 NaN 4.0
2 4.0 4.0
3 NaN 4.0
4 NaN 7.0
5 7.0 7.0
6 NaN 7.0
7 NaN 7.0
8 NaN 1.0
9 NaN 1.0
10 1.0 1.0
11 NaN 1.0
12 NaN 6.0
13 6.0 6.0
14 NaN 6.0
15 NaN 6.0
传递给ToLongFunction
函数,这是它的签名
mapToLong
您传递方法引用long applyAsLong(T value);
-在这里,将您的A::getB
并通过拆箱将其返回(从b
转换为原始{{1 }}。由于为空,因此将导致NPE。
通过尽早进行过滤,可以避免这种情况的发生。
请参阅:https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
答案 2 :(得分:2)
此处
list.stream().mapToLong(A::getB).filter(Objects::nonNull).sum();
您正尝试将列表中的每个B转换为Long,然后不过滤任何null。现在,由于您尚未过滤空值,因此您尝试转换空值。那会抛出NullPointerException。
这里
list.stream().filter(a -> a.getB()!=null).mapToLong(A::getB).sum();
您没有过滤任何null,然后将其映射并转换为Long。在尝试转换时,这里没有null,因为您已经过滤了它们,因此没有NullPointerException。
答案 3 :(得分:2)
为什么此代码失败?
list.stream().mapToLong(A::getB).filter(Objects::nonNull).sum();
因为流操作是顺序执行的。因此,如果对于流A::getB
的任何元素未返回不为空的Long
,则在收集期间将引发异常。
为什么成功?
list.stream().filter(a -> a.getB()!=null).mapToLong(A::getB).sum();
因为首先执行的filter()
删除了导致a::getB
操作的空元素。
因此,您只能在流collection中添加非null元素。所以也不例外。
但是问题是您执行了两次映射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