Stream-map-flatMap .. bad type inference in Eclipse Neon
Stream-map-flatMap ... complexe lambda code for doing simple cartesian product
Here is a simple cartesian product
@Test
public void test2() {
List<Integer> ls1 = range(1,2);
List<Integer> ls2 = range(3,4);
List<String> basicRes = new ArrayList<>();
for(int x1 : ls1) {
for(int x2: ls2) {
basicRes.add(x1 + "-" + x2);
}
}
List<String> expectedRes = Arrays.asList("1-3", "1-4", "2-3", "2-4");
Assert.assertEquals(expectedRes, res);
}
private static List<Integer> range(int start, int end) {
List<Integer> res = new ArrayList<>();
for(int i = start; i <= end; i++) {
res.add(i);
}
return res;
}
Using Jdk8 Lambda … you can do much more complex (but not more compact/readable..)
This-one is still readable..
List<String> foreachRes = new ArrayList<>();
ls1.forEach(x1 -> {
ls2.forEach(x2 -> {
foreachRes.add(x1 + "-" + x2);
});
});
Assert.assertEquals(expectedRes, foreachRes);
Then this one:
List<Integer> ls1 = range(1,2);
List<Integer> ls2 = range(3,4);
List<String> res = ls1.stream().flatMap(x1 ->
ls2.stream().map(x2 ->
x1 + "-" + x2))
.collect(Collectors.toList());
Assert.assertEquals(expectedRes, foreachRes);
Also the non-indented version, make it a good candidate for Obfuscated Code Contest (JCC as CCC ??)
List<String> res = ls1.stream().flatMap(x1 -> ls2.stream().map(x2 -> x1 + "-" + x2)).collect(Collectors.toList());
As far, as Good
Little more ... Eclipse Bug in type inference
Doing the same with 3 cartesian products instead of 2 … it compiles in maven/javac but does not compile anymore in Eclipse !!
List<String> res = ls1.stream().flatMap(x1 ->
ls2.stream().flatMap(x2 ->
ls3.stream().map(x3 ->
x1 + "-" + x2 + "-" + x3)))
.collect(Collectors.toList());
Eclipse says Compile Error: “Type mismatch: cannot convert from List<Object> to List<String>”
This bug is already referenced in eclipse Bugzilla. For example here Eclipse Bugzilla #502158
A workaround is pretty easy, just add an explicit cast to the map() argument:
List<String> castRes = ls1.stream().flatMap((Function<Integer,Stream<String>>) x1 ->
ls2.stream().flatMap(x2 ->
ls3.stream().map(x3 ->
x1 + "-" + x2 + "-" + x3)))
.collect(Collectors.toList());
You can find this source code on my github here: https://github.com/Arnaud-Nauwynck/test-snippets/tree/master/test-map-flatMap