Remove first(with zero index) element from stream conditionally

While the reader will be in an unspecified state after you constructed a stream of lines from it, it is in a well defined state before you do it.

So you can do

String firstLine = reader.readLine();
Stream<String> lines = reader.lines();
if(firstLine != null && !"email".equals(firstLine))
    lines = Stream.concat(Stream.of(firstLine), lines);

Which is the cleanest solution in my opinion. Note that this is not the same as Java 9’s dropWhile, which would drop more than one line if they match.


If you cannot have the list and must do it with only a Stream, you can do it with a variable.

The thing is that you can only use a variable if it is "final" or "effectively final" so you cannot use a literal boolean. You can still do it with an AtomicBoolean :

Stream<String> stream  = Arrays.asList("test", "email", "foo").stream();

AtomicBoolean first = new AtomicBoolean(true);
stream.filter(s -> {
    if (first.compareAndSet(true, false)) {
        return !s.equals("email");
    }
    return true;
})
// Then here, do whatever you need
.forEach(System.out::println);

Note : I don't like using "external variables" in a Stream because side effects are a bad practice in the functional programming paradigm. Better options are welcome.