3
\$\begingroup\$

Between the two implementations, which one is better?

    public static <T> T firstNonNull(final T... values) {
        return Streams.of(values).filter(Objects::nonNull).findFirst().orElse(null);
    }

or

    public static <T> T firstNonNull(final T... values) {
        if (values != null) {
            for (final T val : values) {
                if (val != null) {
                    return val;
                }
            }
        }
        return null;
    }
\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

Your use of streams is good.

It's idiomatic to format this as multiple lines, which makes it even better.

    public static <T> T firstNonNull(final T... values) {
        return Streams.of(values)
            .filter(Objects::nonNull)
            .findFirst()
            .orElse(null);
    }
\$\endgroup\$
3
\$\begingroup\$

In the for loop code, it is explicitly clear how the first non-null value is chosen. We can clearly see that the loop terminates immediately as soon as a non-null is found. The loop does not continue. The code is simple and well-structured.

The Streams version makes the assumption that it is doing the same efficient looping under the hood as your for loop does. If you use it frequently, then you already know its algorithm; otherwise, you need to read the documentation. Although it is one long(-ish) line of code, it is quite readable.

The reason we use code libraries is to avoid re-inventing the wheel. This assumes the library is efficient, well-tested and well-documented.

Documentation

It couldn't hurt to add a short comment to both functions describing the efficeincy.

Performance

You need to benchmark the 2 versions of code to see which performs better using realistic data sets, especially data that you expect to encounter in your application.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.