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> {
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 this.iterators = iterators;
64 if (this.iterators == null || this.iterators.length == 0) {
65 currentIteratorIndex = 1;
66 iterator = null;
67 } else {
68 currentIteratorIndex = 0;
69 previousIterator = null;
70 iterator = iterators[0];
71 switched = false;
72 removed = false;
73 next = false;
74 }
75 }
76
77
78
79
80
81 private boolean nextIterator() {
82 if (iterators == null || currentIteratorIndex >= iterators.length) return false;
83 previousIterator = iterator;
84 switched = true;
85 while (true) {
86 ++currentIteratorIndex;
87 if (currentIteratorIndex >= iterators.length) {
88 return false;
89 }
90 iterator = iterators[currentIteratorIndex];
91 if (iterator == null) continue;
92 if (iterator.hasNext()) {
93 return true;
94 }
95 }
96 }
97
98 @Override
99 public boolean hasNext() {
100 return (iterator != null && iterator.hasNext()) || nextIterator();
101 }
102
103 @Override
104 public NODE next() {
105 if (iterator == null) throw new NoSuchElementException("Last iterator fully used.");
106 if (iterator.hasNext() || nextIterator()) {
107 next = true;
108 switched = false;
109 removed = false;
110 return iterator.next();
111 }
112 throw new NoSuchElementException("Last iterator fully used.");
113 }
114
115 @Override
116 public void remove() {
117 if (!next) throw new IllegalStateException("next() method has never been successfully called, no element to remove!");
118 if (removed) throw new IllegalStateException("remove() was called twice for the same element, unsupported!");
119 if (switched) {
120 previousIterator.remove();
121 } else {
122 iterator.remove();
123 }
124 removed = true;
125 }
126
127 }