Reputation: 802
Can any one explain why the below code will not compile but the second one does?
Do not compile
private void doNotCompile() {
List<Integer> out;
out = IntStream
.range(1, 10)
.filter(e -> e % 2 == 0)
.map(e -> Integer.valueOf(2 * e))
.collect(Collectors.toList());
System.out.println(out);
}
Compilation errors on the collect line
Compiles
private void compiles() {
List<Integer> in;
in = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
List<Integer> out;
out = in.stream()
.filter(e -> e % 2 == 0)
.map(e -> 2 * e)
.collect(Collectors.toList());
System.out.println(out);
}
Upvotes: 3
Views: 3750
Reputation: 393771
IntStream
doesn't have a collect
method that accepts a Collector
. If you want a List<Integer>
, you have to box the IntStream
into a Stream<Integer>
:
out = IntStream
.range(1, 10)
.filter(e -> e % 2 == 0)
.map(e -> 2 * e)
.boxed()
.collect(Collectors.toList());
An alternative to .map().boxed()
is mapToObj()
:
out = IntStream
.range(1, 10)
.filter(e -> e % 2 == 0)
.mapToObj(e -> 2 * e)
.collect(Collectors.toList ());
or you can use the IntStream
collect
method:
out = IntStream
.range(1, 10)
.filter(e -> e % 2 == 0)
.map(e -> 2 * e)
.collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll);
Upvotes: 12
Reputation: 44090
In the first example, you are operating over a stream of primitive integers. Primitive integers can't go into a List
, basically because generics in Java are less than ideal. Java language designers are working on potentially fixing this.
In the meantime, to solve this you need to box these primitive ints into an Integer
wrapper first. See Eran's answer for a code sample.
In the second example, you're already iterating over Integer
s so It Just Works™.
I thought I was boxing those int to Integers when I did Integer.valueOf in the mapper
The map
function of IntStream
takes a IntUnaryOperator
which is a functional interface that takes a primitive int and returns a primitive int.
The Integer
you get from valueOf
is unboxed to match the functional interface.
Upvotes: 2
Reputation: 4266
The collect
method of IntStream
is different in the non-compilable case.
public <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R,R> combiner)
Therefore it does not accept the parameter you supplied to collect
You could get around this by casting List<Integer>
to the IntStream
Upvotes: 1