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