1 package cz.cuni.amis.utils;
2
3 import java.util.Iterator;
4 import java.util.NoSuchElementException;
5
6
7
8
9
10
11
12
13
14
15
16
17 public class Iterators<NODE> implements Iterator<NODE>, Iterable<NODE> {
18
19
20
21
22 private Iterator<NODE>[] iterators;
23
24
25
26
27
28 private int currentIteratorIndex;
29
30
31
32
33
34
35 private Iterator<NODE> previousIterator;
36
37
38
39
40 private Iterator<NODE> iterator;
41
42
43
44
45
46 private boolean switched;
47
48
49
50
51 private boolean removed;
52
53
54
55
56 private boolean next;
57
58
59
60
61
62 public Iterators(Iterator<NODE>... iterators) {
63 init(iterators);
64 }
65
66
67
68
69
70 public Iterators(Iterable<NODE>... iterables) {
71 Iterator<NODE>[] iterators = new Iterator[iterables == null ? 0 : iterables.length];
72 for (int i = 0; i < iterables.length; ++i) {
73 iterators[i] = (iterables[i] == null ? null : iterables[i].iterator());
74 }
75 init(iterators);
76 }
77
78
79
80
81
82 private void init(Iterator<NODE>... iterators) {
83 if (iterators == null || iterators.length == 0) {
84 currentIteratorIndex = 1;
85 iterator = null;
86 } else {
87 this.iterators = iterators;
88 currentIteratorIndex = 0;
89 previousIterator = null;
90 iterator = iterators[0];
91 switched = false;
92 removed = false;
93 next = false;
94 }
95 }
96
97
98
99
100
101 private boolean nextIterator() {
102 if (iterators == null || currentIteratorIndex >= iterators.length) return false;
103 previousIterator = iterator;
104 switched = true;
105 while (true) {
106 ++currentIteratorIndex;
107 if (currentIteratorIndex >= iterators.length) {
108 return false;
109 }
110 iterator = iterators[currentIteratorIndex];
111 if (iterator == null) continue;
112 if (iterator.hasNext()) {
113 return true;
114 }
115 }
116 }
117
118 @Override
119 public boolean hasNext() {
120 return (iterator != null && iterator.hasNext()) || nextIterator();
121 }
122
123 @Override
124 public NODE next() {
125 if (iterator == null) throw new NoSuchElementException("Last iterator fully used.");
126 if (iterator.hasNext() || nextIterator()) {
127 next = true;
128 switched = false;
129 removed = false;
130 return iterator.next();
131 }
132 throw new NoSuchElementException("Last iterator fully used.");
133 }
134
135 @Override
136 public void remove() {
137 if (!next) throw new IllegalStateException("next() method has never been successfully called, no element to remove!");
138 if (removed) throw new IllegalStateException("remove() was called twice for the same element, unsupported!");
139 if (switched) {
140 previousIterator.remove();
141 } else {
142 iterator.remove();
143 }
144 removed = true;
145 }
146
147 @Override
148 public Iterator<NODE> iterator() {
149 return this;
150 }
151
152 }