The naive code I have is:
class ${
public static void main(String[] _) {
final List<Integer> ints = new ArrayList<>();
IntStream.iterate(0, i -> i++).limit(5).forEach(val -> ints.add(val));
System.out.println(ints);
}
}
where my expectation was to see the following in the console:
[0, 1, 2, 3, 4]
But the actual is:
[0, 0, 0, 0, 0]
It is probably something very simple, but what am I missing?
i++
has the value of i
before it's incremented. You need to use the prefix operator.
IntStream.iterate(0, i -> ++i).limit(5).forEach(val -> ints.add(val));
Actually, don't do that. There's no reason to mutate i
, it's simply thrown away. Use the side effect free version. That's the whole idea behind functional programming, after all: avoiding side effects.
IntStream.iterate(0, i -> i + 1).limit(5).forEach(val -> ints.add(val));
For the specific case of a stream of consecutive integers you could replace iterate
and limit
with range
:
IntStream.range(0, 5).forEach(val -> ints.add(val));
And finally, it would also be better to collect the stream into a list rather than adding values with forEach
. It directly expresses the intention to create a list, which again avoids side effects.
List<Integer> ints = IntStream.range(0, 5).boxed().collect(Collectors.toList());
You are using a postfix i++
, instead of a prefix ++i
while passing on the value to forEach
. Changing to the following shall provide you the expected output :
IntStream.iterate(0, i -> i + 1).limit(5).forEach(ints::add);
Aside, an alternate way of iterating and combining limit with Java9+ is using IntStream.iterate
with an IntPredicate
as :
IntStream.iterate(0, i -> i < 5, i -> i + 1).forEach(ints::add);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With