Consider this snippet -
String a = "hello" , b = null, c = "guru";
boolean value = Stream
.of(a, b, b.substring(2),c)
.allMatch(x -> x != null);
System.out.println(value);
This results in NPE. It seems to be doing b.substring(2) and since b is null, NPE is thrown.
Why is this condition evaluated? The second expression b is null and hence evaluates to false.
So, allMatch will be false regardless of the truth values of the subsequent operations. In that case, why is it trying to evaluate b.substring(2)?
This article and this article claim that it may not evaluate all the expressions if not necessary for determining the result. That clearly does not seem to be the case here.
Prior to Java 7 -
if(b != null && b.substring(2) != null)
this would not throw NPE because b!= null is false and it would return false there itself.
So, can we say that Streams.allMatch is not an exact equivalent of the above Java code snippet?
解决方案
Streams.allMatch is not an exact equivalent of the above Java code
snippet?
Of course it is not! Streams are very new way of thinking the processing of data.
Anyway your problem is (not related to this) just that for any function call, arguments are evaluated, thus the call to of necessitate the evaluation of b.subString(2) which obviously throw a NPE.
Related info from the Java Language Specification (emphasize is mine):
15.7.4 Argument Lists are Evaluated Left-to-Right
In a method or constructor invocation or class instance creation
expression, argument expressions may appear within the parentheses,
separated by commas. Each argument expression appears to be fully
evaluated before any part of any argument expression to its right.