Search code examples
javalambdajava-8java-stream

Java 8: Applying Stream map and filter in one go


I am writing a parser for a file in Java 8. The file is read using Files.lines and returns a sequential Stream<String>.

Each line is mapped to a data object Result like this:

Result parse(String _line) {
  // ... code here
  Result _result = new Result().
  if (/* line is not needed */) {
    return null;
  } else {
    /* parse line into result */
   return _result;
  }
}

Now we can map each line in the stream to its according result:

public Stream<Result> parseFile(Path _file) {
  Stream<String> _stream = Files.lines(_file);
  Stream<Result> _resultStream = _stream.map(this::parse);
}

However the stream now contains null values which I want to remove:

parseFile(_file).filter(v -> v != null);

How can I combine the map/filter operation, as I already know in parseLine/_stream.map if the result is needed?


Solution

  • As already pointed out in the comments the stream will be processed in one pass, so there isn't really a need to change anything. For what it's worth you could use flatMap and let parse return a stream:

    Stream<Result> parse(String _line) {
      .. code here
      Result _result = new Result().
      if (/* line is not needed */) {
        return Stream.empty();
      } else {
        /** parse line into result */
       return Stream.of(_result);
      }
    }  
    
    public Stream<Result> parseFile(Path _file) {
      return Files.lines(_file)
                  .flatMap(this::parse);
    }
    

    That way you won't have any null values in the first place.