简体   繁体   中英

How to process data in a list using Java Stream

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!

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

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…

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM