英文:
How to avoid NPE with Collectors.summarizingInt
问题
我们的代码需要从类似以下代码的对象列表中返回最大值和最小值:
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
private Short attr;
public Short getAttr() {
return attr;
}
public static void main(String[] args) {
List<Test> tests = List.of(new Test(), new Test());
IntSummaryStatistics i = tests.stream()
.map(Test::getAttr)
.map(Integer::valueOf)
.filter(in -> in != null && in > 0)
.collect(Collectors.summarizingInt(Integer::intValue));
System.out.println(i.getMax() + " " + i.getMin());
}
}
我们如何避免空指针异常(NPE)?如果没有有效的属性(attrs),我们可以返回零的最大值和最小值。
异常信息:
Exception in thread "main" java.lang.NullPointerException
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:720)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at Test.main(Test.java:20)
英文:
Our code needs to return max and min values from a list of Objects pretty much alike the following code:
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
private Short attr;
public Short getAttr() {
return attr;
}
public static void main (String[] args) {
List<Test> tests = List.of(new Test(), new Test());
IntSummaryStatistics i = tests.stream()
.map(Test::getAttr)
.map(Integer::valueOf)
.filter(in -> in != null && in > 0)
.collect(Collectors.summarizingInt(Integer::intValue));
System.out.println(i.getMax() + " " + i.getMin());
}
}
How could we avoid NPE (null pointer exception)? In case of no valid attrs we can return zero max and min.
Exception message:
Exception in thread "main" java.lang.NullPointerException
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:720)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at Test.main(Test.java:20)
答案1
得分: 3
NPE 在以下代码中被抛出:
.map(Integer::valueOf)
因为 Integer#valueOf(int)
会对输入进行拆箱操作,可能导致 NPE(空指针异常)。
为了解决这个问题,我建议采取以下其中一种方法。
- (由 Holger 提出的建议)删除
.map(Integer::valueOf)
这部分,并且在Collectors.summarizingInt
内部将Short
映射为int
(使用Short::intValue
),如下所示:
IntSummaryStatistics i = tests.stream()
.map(Test::getAttr)
.filter(in -> in != null && in > 0)
.collect(Collectors.summarizingInt(Short::intValue));
请注意,当流为空时,IntSummaryStatistics#getMax 和 getMin 将分别为 Integer.MIN_VALUE
和 Integer.MAX_VALUE
(不直观!!)。
因此输出将会是 -2147483648 2147483647
。
- 为
attr
提供一个默认值(也许是 0)。
英文:
The NPE is thrown in
.map(Integer::valueOf)
as Integer#valueOf(int)
will unbox the input and cause NPE.
To solve the problem, I suggest one of the following way.
- (Suggested by Holger) Delete
.map(Integer::valueOf)
and mapShort
toint
(Short::intValue
) insideCollectors.summarizingInt
as follow:
IntSummaryStatistics i = tests.stream()
.map(Test::getAttr)
.filter(in -> in != null && in > 0)
.collect(Collectors.summarizingInt(Short::intValue));
Please note that IntSummaryStatistics#getMax and getMin will be Integer.MIN_VALUE
and Integer.MAX_VALUE
respectively (not intuitive!!) when the stream is empty.
Hence the output will be -2147483648 2147483647
.
- Provide default value (maybe 0) for
attr
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论