The simplest approach is a 1:1 translation of the loop
IntStream.range(0, list.size())
.forEach(i -> IntStream.range(i+1, list.size())
.forEach(j -> System.out.println("i :"+list.get(i)+"J :"+list.get(j))));
You could also use
IntStream.range(0, list.size())
.forEach(i -> list.subList(i+1, list.size())
.forEach(o -> System.out.println("i :"+list.get(i)+"J :"+o)));
which would be the equivalent of
for(int i = 0; i < list.size(); i++) {
for(Integer o: list.subList(i + 1, list.size())) {
System.out.println("i :" + list.get(i) + "J :" + o);
}
}
though it would be better to do
for(int i = 0; i < list.size(); i++) {
Integer o = list.get(i);
String prefix = "i :" + o + "J :";
for(Integer p: list.subList(i + 1, list.size())) {
System.out.println(prefix + p);
}
}
reducing the redundant work.
A more declarative approach is
IntStream.range(0, list.size()).boxed()
.flatMap(i -> IntStream.range(i+1, list.size())
.mapToObj(j -> ("i :"+list.get(i)+"J :"+list.get(j))))
.forEach(System.out::println);
Unfortunately, the alternative with the reduced redundant work can’t be expressed as Stream operation easily, due to the lack of a simple-to-use pair type. One solution would be:
IntStream.range(0, list.size())
.mapToObj(i -> new Object(){ int index=i; String prefix="i :"+list.get(i)+"J :";})
.flatMap( p -> list.subList(p.index+1, list.size()).stream().map(o -> p.prefix+o))
.forEach(System.out::println);
Obviously, that’s not more readable than the nested for loops…
IntStream.range(0, list.size()) .forEach(i -> IntStream.range(i + 1, list.size()).forEach(j -> System.out.println("i :" + list.get(i) + "J :" + list.get(j)) ));