1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.set;
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.HashSet;
22 import java.util.List;
23 import java.util.ListIterator;
24 import java.util.Objects;
25 import java.util.Set;
26 import java.util.function.Predicate;
27
28 import org.apache.commons.collections4.CollectionUtils;
29 import org.apache.commons.collections4.OrderedIterator;
30 import org.apache.commons.collections4.functors.UniquePredicate;
31 import org.apache.commons.collections4.iterators.AbstractIteratorDecorator;
32 import org.apache.commons.collections4.list.UnmodifiableList;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class ListOrderedSet<E>
61 extends AbstractSerializableSetDecorator<E> {
62
63
64
65
66 static class OrderedSetIterator<E>
67 extends AbstractIteratorDecorator<E>
68 implements OrderedIterator<E> {
69
70
71 private final Collection<E> set;
72
73
74 private E last;
75
76 private OrderedSetIterator(final ListIterator<E> iterator, final Collection<E> set) {
77 super(iterator);
78 this.set = set;
79 }
80
81 @Override
82 public boolean hasPrevious() {
83 return ((ListIterator<E>) getIterator()).hasPrevious();
84 }
85
86 @Override
87 public E next() {
88 last = getIterator().next();
89 return last;
90 }
91
92 @Override
93 public E previous() {
94 last = ((ListIterator<E>) getIterator()).previous();
95 return last;
96 }
97
98 @Override
99 public void remove() {
100 set.remove(last);
101 getIterator().remove();
102 last = null;
103 }
104 }
105
106
107 private static final long serialVersionUID = -228664372470420141L;
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 public static <E> ListOrderedSet<E> listOrderedSet(final List<E> list) {
124 Objects.requireNonNull(list, "list");
125 CollectionUtils.filter(list, UniquePredicate.uniquePredicate());
126 final Set<E> set = new HashSet<>(list);
127
128 return new ListOrderedSet<>(set, list);
129 }
130
131
132
133
134
135
136
137
138
139
140
141
142 public static <E> ListOrderedSet<E> listOrderedSet(final Set<E> set) {
143 return new ListOrderedSet<>(set);
144 }
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 public static <E> ListOrderedSet<E> listOrderedSet(final Set<E> set, final List<E> list) {
160 Objects.requireNonNull(set, "set");
161 Objects.requireNonNull(list, "list");
162 if (!set.isEmpty() || !list.isEmpty()) {
163 throw new IllegalArgumentException("Set and List must be empty");
164 }
165 return new ListOrderedSet<>(set, list);
166 }
167
168
169 private final List<E> setOrder;
170
171
172
173
174
175
176
177 public ListOrderedSet() {
178 super(new HashSet<>());
179 setOrder = new ArrayList<>();
180 }
181
182
183
184
185
186
187
188 protected ListOrderedSet(final Set<E> set) {
189 super(set);
190 setOrder = new ArrayList<>(set);
191 }
192
193
194
195
196
197
198
199
200
201
202
203 protected ListOrderedSet(final Set<E> set, final List<E> list) {
204 super(set);
205 setOrder = Objects.requireNonNull(list, "list");
206 }
207
208 @Override
209 public boolean add(final E object) {
210 if (decorated().add(object)) {
211 setOrder.add(object);
212 return true;
213 }
214 return false;
215 }
216
217
218
219
220
221
222
223
224
225
226 public void add(final int index, final E object) {
227 if (!contains(object)) {
228 decorated().add(object);
229 setOrder.add(index, object);
230 }
231 }
232
233 @Override
234 public boolean addAll(final Collection<? extends E> coll) {
235 boolean result = false;
236 for (final E e : coll) {
237 result |= add(e);
238 }
239 return result;
240 }
241
242
243
244
245
246
247
248
249
250
251
252
253 public boolean addAll(final int index, final Collection<? extends E> coll) {
254 boolean changed = false;
255
256 final List<E> toAdd = new ArrayList<>();
257 for (final E e : coll) {
258 if (contains(e)) {
259 continue;
260 }
261 decorated().add(e);
262 toAdd.add(e);
263 changed = true;
264 }
265
266 if (changed) {
267 setOrder.addAll(index, toAdd);
268 }
269
270 return changed;
271 }
272
273
274
275
276
277
278 public List<E> asList() {
279 return UnmodifiableList.unmodifiableList(setOrder);
280 }
281
282 @Override
283 public void clear() {
284 decorated().clear();
285 setOrder.clear();
286 }
287
288
289
290
291
292
293
294
295 public E get(final int index) {
296 return setOrder.get(index);
297 }
298
299
300
301
302
303
304
305
306
307
308 public int indexOf(final Object object) {
309 return setOrder.indexOf(object);
310 }
311
312 @Override
313 public OrderedIterator<E> iterator() {
314 return new OrderedSetIterator<>(setOrder.listIterator(), decorated());
315 }
316
317
318
319
320
321
322
323
324
325 public E remove(final int index) {
326 final E obj = setOrder.remove(index);
327 remove(obj);
328 return obj;
329 }
330
331 @Override
332 public boolean remove(final Object object) {
333 final boolean result = decorated().remove(object);
334 if (result) {
335 setOrder.remove(object);
336 }
337 return result;
338 }
339
340 @Override
341 public boolean removeAll(final Collection<?> coll) {
342 boolean result = false;
343 for (final Object name : coll) {
344 result |= remove(name);
345 }
346 return result;
347 }
348
349
350
351
352 @Override
353 public boolean removeIf(final Predicate<? super E> filter) {
354 if (Objects.isNull(filter)) {
355 return false;
356 }
357 final boolean result = decorated().removeIf(filter);
358 if (result) {
359 setOrder.removeIf(filter);
360 }
361 return result;
362 }
363
364
365
366
367
368
369
370
371
372
373 @Override
374 public boolean retainAll(final Collection<?> coll) {
375 final boolean result = decorated().retainAll(coll);
376 if (!result) {
377 return false;
378 }
379 if (decorated().isEmpty()) {
380 setOrder.clear();
381 } else {
382 setOrder.removeIf(e -> !decorated().contains(e));
383 }
384 return result;
385 }
386
387 @Override
388 public Object[] toArray() {
389 return setOrder.toArray();
390 }
391
392 @Override
393 public <T> T[] toArray(final T[] a) {
394 return setOrder.toArray(a);
395 }
396
397
398
399
400
401
402
403
404
405 @Override
406 public String toString() {
407 return setOrder.toString();
408 }
409
410 }