1 /*
2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.tools.javac.util;
27 
28 import java.util.Iterator;
29 import java.util.NoSuchElementException;
30 import java.util.function.Function;
31 import java.util.function.Predicate;
32 
33 /** Utilities for Iterators.
34  *
35  *  <p><b>This is NOT part of any supported API.
36  *  If you write code that depends on this, you do so at your own risk.
37  *  This code and its internal interfaces are subject to change or
38  *  deletion without notice.</b>
39  */
40 public class Iterators {
41 
createCompoundIterator(Iterable<I> inputs, Function<I, Iterator<O>> convertor)42     public static <I, O> Iterator<O> createCompoundIterator(Iterable<I> inputs, Function<I, Iterator<O>> convertor) {
43         return new CompoundIterator<>(inputs, convertor);
44     }
45 
46     private static class CompoundIterator<I, O> implements Iterator<O> {
47 
48         private final Iterator<I> inputs;
49         private final Function<I, Iterator<O>> convertor;
50         @SuppressWarnings("unchecked")
51         private Iterator<O> currentIterator = EMPTY;
52 
CompoundIterator(Iterable<I> inputs, Function<I, Iterator<O>> convertor)53         public CompoundIterator(Iterable<I> inputs, Function<I, Iterator<O>> convertor) {
54             this.inputs = inputs.iterator();
55             this.convertor = convertor;
56         }
57 
hasNext()58         public boolean hasNext() {
59             if (currentIterator != null && !currentIterator.hasNext()) {
60                 update();
61             }
62             return currentIterator != null;
63         }
64 
next()65         public O next() {
66             if (currentIterator == EMPTY && !hasNext()) {
67                 throw new NoSuchElementException();
68             }
69             return currentIterator.next();
70         }
71 
remove()72         public void remove() {
73             throw new UnsupportedOperationException();
74         }
75 
update()76         private void update() {
77             while (inputs.hasNext()) {
78                 currentIterator = convertor.apply(inputs.next());
79                 if (currentIterator.hasNext()) return;
80             }
81             currentIterator = null;
82         }
83     }
84 
85     @SuppressWarnings("rawtypes")
86     private final static Iterator EMPTY = new Iterator() {
87         public boolean hasNext() {
88             return false;
89         }
90 
91         @Override
92         public Object next() {
93             return null;
94         }
95     };
96 
createFilterIterator(Iterator<E> input, Predicate<E> test)97     public static <E> Iterator<E> createFilterIterator(Iterator<E> input, Predicate<E> test) {
98         return new Iterator<E>() {
99             private E current = update();
100             private E update () {
101                 while (input.hasNext()) {
102                     E sym = input.next();
103                     if (test.test(sym)) {
104                         return sym;
105                     }
106                 }
107 
108                 return null;
109             }
110             @Override
111             public boolean hasNext() {
112                 return current != null;
113             }
114 
115             @Override
116             public E next() {
117                 E res = current;
118                 current = update();
119                 return res;
120             }
121         };
122     }
123 
124 }
125