Java lambda空指针踩坑

0

使用findFirst方法会出现以下错误:

java.lang.NullPointerException
	at java.base/java.util.Objects.requireNonNull(Objects.java:221)
	at java.base/java.util.Optional.<init>(Optional.java:107)
	at java.base/java.util.Optional.of(Optional.java:120)
	at java.base/java.util.stream.FindOps$FindSink$OfRef.get(FindOps.java:194)
	at java.base/java.util.stream.FindOps$FindSink$OfRef.get(FindOps.java:191)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:543)
	at com.acgist.snail/com.acgist.snail.LambdaTest.testNull(LambdaTest.java:53)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)

下面是代码:

@Test
public void testNull() {
	Map<Integer, String> map = new HashMap<Integer, String>();
	map.put(1, null);
	map.put(2, null);
	var value = map.entrySet().stream()
		.filter(entry -> entry.getKey() == 1)
		.findFirst()
		.orElse(null);
	this.log(value);
	value = map.entrySet().stream()
		.filter(entry -> entry.getKey() == 1)
		.findFirst()
		.orElse(null);
	this.log(value);
	var valueMap = map.entrySet().stream()
		.filter(entry -> entry.getKey() == 1)
		.map(Entry::getValue)
		.filter(Objects::nonNull)
		.findFirst()
		.orElse(null);
	this.log(valueMap);
	valueMap = map.entrySet().stream()
		.filter(entry -> entry.getKey() == 1)
		.map(Entry::getValue)
		.findFirst() // 空指针
		.orElse("没有");
	this.log(valueMap);
}

@Test
public void testNullEx() {
	Map<Integer, String> map = new HashMap<Integer, String>();
	map.put(1, null);
	map.put(2, null);
	var value = map.entrySet().stream()
		.filter(entry -> entry.getKey() == 3)
		.findFirst()
		.orElse(null);
	this.log(value);
	value = map.entrySet().stream()
		.filter(entry -> entry.getKey() == 3)
		.findFirst()
		.orElse(null);
	this.log(value);
	var valueMap = map.entrySet().stream()
		.filter(entry -> entry.getKey() == 3)
		.map(Entry::getValue)
		.filter(Objects::nonNull)
		.findFirst()
		.orElse(null);
	this.log(valueMap);
	valueMap = map.entrySet().stream()
		.filter(entry -> entry.getKey() == 3)
		.map(Entry::getValue)
		.findFirst()
		.orElse("没有");
	this.log(valueMap);
}

标记的地方就会出现空指针,这里主要是因为Map里面value是空,所以导致了创建Optional抛了空指针,所以需要优先判断一下.filter(Objects::nonNull)

其实这里JDK应该优化一下,如果使用Optional.ofNullable替换Optional.of,这里就不会空指针了。
如果每次需要我们手动判断不是非常友好。