How to iterate nested lists with lambda streams?

前端 未结 6 1828
眼角桃花
眼角桃花 2021-02-12 20:16

I\'m trying to refactor the following code to lambda expressions with `stream, especially the nested foreach loops:

public static Result match (Response rsp) {
          


        
6条回答
  •  无人及你
    2021-02-12 20:25

    You could use that fact that StreamSupport provides a stream method that takes a Spliterator and Iterable has a spliterator method.

    You then just need a mechanism to flatten your structure into an Iterable - something like this.

    class IterableIterable implements Iterable {
    
        private final Iterable> i;
    
        public IterableIterable(Iterable> i) {
            this.i = i;
        }
    
        @Override
        public Iterator iterator() {
            return new IIT();
        }
    
        private class IIT implements Iterator {
    
            // Pull an iterator.
            final Iterator> iit = i.iterator();
            // The current Iterator
            Iterator it = null;
            // The current T.
            T next = null;
    
            @Override
            public boolean hasNext() {
                boolean finished = false;
                while (next == null && !finished) {
                    if (it == null || !it.hasNext()) {
                        if (iit.hasNext()) {
                            it = iit.next().iterator();
                        } else {
                            finished = true;
                        }
                    }
                    if (it != null && it.hasNext()) {
                        next = it.next();
                    }
                }
                return next != null;
            }
    
            @Override
            public T next() {
                T n = next;
                next = null;
                return n;
            }
        }
    
    }
    
    public void test() {
        List> list = new ArrayList<>();
        List first = new ArrayList<>();
        first.add("First One");
        first.add("First Two");
        List second = new ArrayList<>();
        second.add("Second One");
        second.add("Second Two");
        list.add(first);
        list.add(second);
        // Check it works.
        IterableIterable l = new IterableIterable<>(list);
        for (String s : l) {
            System.out.println(s);
        }
        // Stream it like this.
        Stream stream = StreamSupport.stream(l.spliterator(), false);
    }
    

    You can now stream directly from your Iterable.

    Initial research suggests that this should be done with flatMap but whatever.

提交回复
热议问题