196. Null-safe streams

The problem with creating a Stream of an element that may or may not be null can be solved using Optional.ofNullable() or, even better via JDK 9, Stream.ofNullable():

  • static <T> Stream<T> ofNullable​(T t)

This method gets a single element (T) and returns a sequential Stream containing this single element (Stream<T>); otherwise, it returns an empty Stream if it's not null.

For example, we can write a helper method that wraps the call to Stream.ofNullable() as follows:

public static <T> Stream<T> elementAsStream(T element) {
return Stream.ofNullable(element);
}

If this method lives in a utility class named AsStreams, then we can perform several calls, as follows:

// 0
System.out.println("Null element: "
+ AsStreams.elementAsStream(null).count());

// 1
System.out.println("Non null element: "
+ AsStreams.elementAsStream("Hello world").count());

Notice that when we pass null, we get an empty stream (the count() method returns 0)!

If our element is a collection, then things become more interesting. For example, let's assume that we have the following list (notice that this list contains some null values):

List<Integer> ints = Arrays.asList(5, null, 6, null, 1, 2);

Now, let's write a helper method that returns a Stream<T>, where T is a collection:

public static <T> Stream<T> collectionAsStreamWithNulls(
Collection<T> element) {
return Stream.ofNullable(element).flatMap(Collection::stream);
}

If we call this method with null, then we obtain an empty stream:

// 0
System.out.println("Null collection: "
+ AsStreams.collectionAsStreamWithNulls(null).count());

Now, if we call it with our list, ints, then we obtain a Stream<Integer>:

// 6
System.out.println("Non-null collection with nulls: "
+ AsStreams.collectionAsStreamWithNulls(ints).count());

Notice that the stream has six elements (all the elements from the underlying list)—5, null, 6, null, 1, and 2.

If we know that the collection itself is not null, but it may contain null values, then we can write another helper method, as follows:

public static <T> Stream<T> collectionAsStreamWithoutNulls(
Collection<T> collection) {

return collection.stream().flatMap(e -> Stream.ofNullable(e));
}

This time, if the collection itself is null, then the code will throw an NullPointerException. However, if we pass our list to it, then the result will be a Stream<Integer> without null values:

// 4
System.out.println("Non-null collection without nulls: "
+ AsStreams.collectionAsStreamWithoutNulls(ints).count());

The returned stream has only four elements—5, 6, 1, and 2.

Finally, if the collection itself may be null and may contain null values, then the following helper will do the job and return a null-safe stream:

public static <T> Stream<T> collectionAsStream(
Collection<T> collection) {

return Stream.ofNullable(collection)
.flatMap(Collection::stream)
.flatMap(Stream::ofNullable);
}

If we pass null, then we get an empty stream:

// 0
System.out.println(
"Null collection or non-null collection with nulls: "
+ AsStreams.collectionAsStream(null).count());

If we pass our list, we get a Stream<Integer> stream without null values:

// 4
System.out.println(
"Null collection or non-null collection with nulls: "
+ AsStreams.collectionAsStream(ints).count());
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.67.5