There are two completely different things you should ask here:
a) how do I place multiple lines of code in stream.forEach()?
b) what should I do to count the number of lines in a Stream?
The question b) is answered already by other posters; on the other hand, the general question a) has a quite different answer:
use a (possibly multi-line) lambda expression or pass a reference to multi-line method.
In this particular case, you'd either declare i a field or use a counter/wrapper object instead of i.
For example, if you want to have multiple lines in forEach() explicitly, you can use
class Counter { // wrapper class
private int count;
public int getCount() { return count; }
public void increaseCount() { count++; }
}
and then
Counter counter = new Counter();
lines.stream().forEach( e -> {
System.out.println(e);
counter.increaseCounter(); // or i++; if you decided i is worth being a field
} );
Another way to do it, this time hiding those multiple lines in a method:
class Counter { // wrapper class
private int count;
public int getCount() { return count; }
public void increaseCount( Object o ) {
System.out.println(o);
count++;
}
}
and then
Counter counter = new Counter();
lines.stream().forEach( counter::increaseCount );
or even
Counter counter = new Counter();
lines.stream().forEach( e -> counter.increaseCount(e) );
The second syntax comes in handy if you need a consumer having more than one parameter; the first syntax is still the shortest and simplest though.