fastcodejava :
I have this code, but it gives me an error:
Type mismatch: cannot convert from int to Character
Stream.iterate('a', i -> i + 1).limit(26).forEach(System.out::println);
Although it is fine to write int i = 'a';
I know I can write it like this, but that seems like too much code for a simple task.
Stream.iterate('a', i -> (char)(i + 1)).limit(26).forEach(System.out::println);
Why is the Java type inference failing?
Ousmane D. :
The reason why i -> i + 1
does not compile is because you're attempting to implicitly convert an int
to a Character
which the compiler cannot do itself alone.
In other words, you can think of Stream.iterate('a', i -> i + 1)
as:
Stream.iterate('a', (Character i) -> {
int i1 = i + 1;
return i1; // not possible
});
As you have noted, explicitly casting to char
solves it:
Stream.iterate('a', i -> (char)(i + 1))...
Btw this is better done as:
IntStream.rangeClosed('a', 'z').forEach(c -> System.out.println((char)c));
This is better because:
- No boxing overhead thus more efficient
- if you were to stop at say letter
h
with the use ofiterate
you'd have to do more brain processing than just enteringh
as the upper bound withrangeClosed
because you'd need to find the number to truncate the infinite stream upon. - Along with the boxing
iterate
generates an infinite stream which in this specific case has more overhead than the finite one withrangeClosed
. Further, it's far easier to runIntStream.rangeClosed
in parallel, not that you want to in this specific case but it's something to keep in mind. here is some discussion on Generators as sources by Brian Goetz.
etc...