Are the || ('or') symbol and Stream.of(..).anyMatch(e-> e==true) functionally equivalent?

jfr :

Are || and Stream.of(..).anyMatch(e-> e==true) functionally equivalent when applied to the same series of conditions in the same order?

Task: Run a quick test on a series of conditions to determine whether any are true.

Possible solutions: - Separate each condition with an ‘or’ symbol (||) - Include each condition in a Stream.of(..) statement that is appended with .anyMatch(e-> e==true)

The documentation for anyMatch(..) states, “Returns whether any elements of this stream match the provided predicate. May not evaluate the predicate on all elements if not necessary for determining the result [emphasis added].”

Based on this statement, my understanding is that the two solutions indicated above are functionally the same, so that if the second element in a serious of four is the first element that is true, then elements three and four won’t be evaluated.

In practice, however, this seems not to be true. Consider the following where item is null, empty is true and UtilMethods.isEmpty(..) is a custom library method that tests if a given parameter is null or an empty String (""):

@Override
protected void updateItem(Pair<K, V> item, boolean empty) {
    super.updateItem(item, empty);

    boolean test1 = empty
             || Objects.isNull(item)
             || UtilMethods.isEmpty(item.toString())
             || Objects.isNull(item.getValue());

    boolean test2 = Stream.of(
        empty,
        isNull(item),
        UtilMethods.isEmpty(item.toString()),
        isNull(item.getValue()))
    .anyMatch(e -> e == true);
}

The || code runs as expected. However, the Stream.of(..).anyMatch(..) throws a NullPointerException when the third element is reached because item is null.

This doesn’t make sense in view of the documentation for anyMatch(..) that is referenced above, which suggests that the third element shouldn’t even be reached. Or am I missing something here?

Thanks

Eran :

UtilMethods.isEmpty(item.toString()) is evaluated before Stream.of() is executed, so it will throw a NullPointerException regardless of whether or not you call anyMatch afterwards.

Stream.of(), just as any method call, evaluates all of its arguments before being executed, so it must evaluate UtilMethods.isEmpty(item.toString()).

You can see the same behavior in a much simpler snippet:

String s = null;
Stream<Integer> stream = Stream.of (5,s.length());

Hence, the documentation of anyMatch is irrelevant to the behavior you observed.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=276448&siteId=1