1 package cz.cuni.amis.utils.iterators;
2
3 import java.util.Iterator;
4 import java.util.List;
5 import java.util.ListIterator;
6
7
8
9
10
11
12
13
14
15 public class CircularListIterator<E> implements ListIterator<E> {
16
17 protected boolean passedEnd = false;
18 protected boolean passedBeginning = false;
19
20 protected boolean moved = false;
21
22 private int index = 0;
23 private List<E> toIterateOver;
24 private ListIterator<E> iterator;
25
26
27
28
29
30 public CircularListIterator(List<E> toIterateOver) {
31 if (toIterateOver == null)
32 throw new NullPointerException("List<E> to be iterated over cannot be null.");
33
34 this.toIterateOver = toIterateOver;
35 iterator = toIterateOver.listIterator();
36 }
37
38
39
40
41
42
43 public CircularListIterator(List<E> toIterateOver, int index) {
44 if (toIterateOver == null)
45 throw new IllegalArgumentException("List<E> to be iterated over cannot be null.");
46
47 if (index < 0 && index > toIterateOver.size())
48 throw new IllegalArgumentException("Index parameter cannot be outside toIterateOver parameter.");
49
50 this.toIterateOver = toIterateOver;
51 iterator = toIterateOver.listIterator(index);
52 this.index = index;
53 }
54
55
56
57
58
59 public CircularListIterator(CircularListIterator<E> source) {
60 this.passedEnd = source.passedEnd;
61 this.passedBeginning = source.passedBeginning;
62 this.index = source.index;
63 this.toIterateOver = source.toIterateOver;
64
65 int currentIndex = source.currentIndex();
66
67 this.iterator = toIterateOver.listIterator(
68 (currentIndex == -1 ? toIterateOver.size() - 1 : currentIndex));
69 }
70
71 @Override
72 public boolean hasNext() {
73 return toIterateOver.size() > 0;
74 }
75
76 @Override
77 public E next() {
78
79 if (currentIndex() == toIterateOver.size()) {
80 restartIteratorBeginning();
81 }
82
83 E value = iterator.next();
84
85 if (currentIndex() == index && moved)
86 passedEnd = true;
87
88 moved = true;
89
90 return value;
91 }
92
93 @Override
94 public void remove() {
95
96 iterator.remove();
97
98 if (currentIndex() == index)
99 passedEnd = true;
100
101 if (currentIndex() == toIterateOver.size()) {
102 restartIteratorBeginning();
103 }
104
105 }
106
107 public boolean hasPassedEnd() {
108 if (passedEnd) {
109 passedEnd = false;
110 return passedEnd;
111 }
112 return false;
113 }
114
115 public boolean hasPassedBeginning() {
116 if (passedBeginning) {
117 passedBeginning = false;
118 return passedBeginning;
119 }
120 return false;
121 }
122
123 protected Iterable<E> getIterable() {
124 return toIterateOver;
125 }
126
127 protected Iterator<E> getIterator() {
128 return iterator;
129 }
130
131 protected void restartIteratorBeginning() {
132 iterator = toIterateOver.listIterator();
133 }
134
135 protected void restartIteratorEnd() {
136 iterator = toIterateOver.listIterator(toIterateOver.size());
137 }
138
139 @Override
140 public void add(E e) {
141 iterator.add(e);
142 }
143
144 @Override
145 public boolean hasPrevious() {
146 return hasNext();
147 }
148
149 @Override
150 public int nextIndex() {
151 return (iterator.nextIndex() % toIterateOver.size());
152 }
153
154 @Override
155 public E previous() {
156
157 if (currentIndex() == 0) {
158 restartIteratorEnd();
159 }
160
161 E value = iterator.previous();
162
163 if (currentIndex() == index && moved)
164 passedBeginning = true;
165
166 moved = true;
167
168 return value;
169 }
170
171 @Override
172 public int previousIndex() {
173 int previous = iterator.previousIndex();
174 return (previous == -1 ? toIterateOver.size() - 1 : previous);
175 }
176
177 @Override
178 public void set(E e) {
179 iterator.set(e);
180 }
181
182 public int currentIndex() {
183 int next = nextIndex() - 1;
184
185 return (next == toIterateOver.size() ? 0 : (nextIndex() - 1));
186 }
187
188 public CircularListIterator<E> previousIter() {
189 this.previous();
190 return this;
191 }
192
193 public CircularListIterator<E> nextIter() {
194 this.next();
195 return this;
196 }
197 }