2

How to iterate over 2 loops in a List using Java Stream.

public class ArrayStreams {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(3);
        list.add(5);
        list.add(7);
        list.add(2);

for (int i = 0; i < list.size(); i++) {
            for (int j = i + 1; j < list.size(); j++) {
                System.out.println("i :" + list.get(i) + "J :" + list.get(j));
            }
        }

    }
}

How can i convert this code into Java Stream. Please help!

4
  • 2
    Why do you want to convert it into Java Stream? Commented Mar 19, 2018 at 20:08
  • I am converting all the code to Java 8 for better readability. Commented Mar 19, 2018 at 20:09
  • 6
    Why do you think streams would express this logic in a more readable way if you don't know how to write it? Commented Mar 19, 2018 at 20:11
  • not sure whether it's more readable to you or not but this is the equivalent --> 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)) )); Commented Mar 19, 2018 at 21:13

2 Answers 2

6

How can i convert this code into Java Stream.

You should not use Streams for at least two reasons :

  • you don't iterate all elements in the second loop, so you should skip the first element in the inner loop.
  • and above all you use indexes of the list in your println(). Streams are not designed to maintain index of the streamed elements
Sign up to request clarification or add additional context in comments.

2 Comments

agree with this answer, although if one wanted to maintain an index and at the same time be able to use the element at that index then using IntStream.range may be an option.
@Aominè It is an option indeed but we cannot recommend it. That' s why, I said : "you should" and not "you cannot". Streaming on ints rather than objects contained in the list and using two foreach() don't appear as a stream/functional way processing but looks like more to a unfortunate way to convert an imperative code to a stream.
2

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…

1 Comment

Really fine code illustrating why whatever the way streams will produce a code more convoluted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.