Search code examples
javachecker-framework

convert from Stream<@Nullable T> to Stream<@NonNull T> using stream api


I use CheckerFramework

How could I remove nulls from Stream and got collection of @NonNull objects?

Stream<@Nullable T> -> (remove nulls) -> Stream<@NonNull T>

Solution

  • Here is code that does it.

    import java.util.Objects;
    import java.util.stream.Stream;
    import org.checkerframework.checker.nullness.qual.NonNull;
    import org.checkerframework.checker.nullness.qual.Nullable;
    
    class RemoveNullsFromStream {
    
      @SuppressWarnings("nullness") // Nullness Checker is not hard-coded with
                      // implementation details of filter and Objects::nonNull
      <T>
      Stream<@NonNull T> removeNullsFromStream(Stream<@Nullable T> arg) {
        return arg.filter(Objects::nonNull);
      }
    
    }
    

    Note the use of @SuppressWarnings, because the Nullness Checker is conservative: it issues a warning whenever it cannot definitively prove the code is safe. In general, the output of filter is the same as its input; when the argument to filter is Objects::nonNull is a special case.

    That special-case could be hard-coded into the Nullness Checker, and that would make the Nullness Checker more precise. This behavior is not currently special-cased, so you use @SuppressWarnings instead.