Remember, a lambda expression is a way of representing, as an anonymous function, the implementation of a functional interface (an interface that has only one abstract method).
In your iterate() method, the third argument is an IntUnaryOperator. This has a single abstract method, applyAsInt(), which takes an int as an argument and returns an int. If you re-write the Lambda expression as the equivalent anonymous inner class (which you can quite legitimately use here), you get:
IntStream.iterate(0, i -> i < 10, new IntUnaryOperator() {
@Override
public int applyAsInt(int i) {
return i++;
}
})
.forEach(System.out::println);
In this case, it is clear that you are returning the value of i before it is incremented (postfix operator). The initial value of i is zero so you will get an infinite stream of zeros. If you change the applyAsInt() method to use the prefix operator, ++i, the value of i will be incremented before being returned giving you the desired result of 1, 2 ... 9