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
124
125 public static <E> ListOrderedSet<E> listOrderedSet(final List<E> list) {
126 Objects.requireNonNull(list, "list");
127 CollectionUtils.filter(list, UniquePredicate.uniquePredicate());
128 final Set<E> set = new HashSet<>(list);
129
130 return new ListOrderedSet<>(set, list);
131 }
132
133
134
135
136
137
138
139
140
141
142
143
144
145 public static <E> ListOrderedSet<E> listOrderedSet(final Set<E> set) {
146 return new ListOrderedSet<>(set);
147 }
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163 public static <E> ListOrderedSet<E> listOrderedSet(final Set<E> set, final List<E> list) {
164 Objects.requireNonNull(set, "set");
165 Objects.requireNonNull(list, "list");
166 if (!set.isEmpty() || !list.isEmpty()) {
167 throw new IllegalArgumentException("Set and List must be empty");
168 }
169 return new ListOrderedSet<>(set, list);
170 }
171
172
173 private final List<E> setOrder;
174
175
176
177
178
179
180
181 public ListOrderedSet() {
182 super(new HashSet<>());
183 setOrder = new ArrayList<>();
184 }
185
186
187
188
189
190
191
192 protected ListOrderedSet(final Set<E> set) {
193 super(set);
194 setOrder = new ArrayList<>(set);
195 }
196
197
198
199
200
201
202
203
204
205
206
207
208 protected ListOrderedSet(final Set<E> set, final List<E> list) {
209 super(set);
210 setOrder = Objects.requireNonNull(list, "list");
211 }
212
213 @Override
214 public boolean add(final E object) {
215 if (decorated().add(object)) {
216 setOrder.add(object);
217 return true;
218 }
219 return false;
220 }
221
222
223
224
225
226
227
228
229
230
231 public void add(final int index, final E object) {
232 if (!contains(object)) {
233 decorated().add(object);
234 setOrder.add(index, object);
235 }
236 }
237
238 @Override
239 public boolean addAll(final Collection<? extends E> coll) {
240 boolean result = false;
241 for (final E e : coll) {
242 result |= add(e);
243 }
244 return result;
245 }
246
247
248
249
250
251
252
253
254
255
256
257
258 public boolean addAll(final int index, final Collection<? extends E> coll) {
259 boolean changed = false;
260
261 final List<E> toAdd = new ArrayList<>();
262 for (final E e : coll) {
263 if (contains(e)) {
264 continue;
265 }
266 decorated().add(e);
267 toAdd.add(e);
268 changed = true;
269 }
270
271 if (changed) {
272 setOrder.addAll(index, toAdd);
273 }
274
275 return changed;
276 }
277
278
279
280
281
282
283 public List<E> asList() {
284 return UnmodifiableList.unmodifiableList(setOrder);
285 }
286
287 @Override
288 public void clear() {
289 decorated().clear();
290 setOrder.clear();
291 }
292
293
294
295
296
297
298
299
300 public E get(final int index) {
301 return setOrder.get(index);
302 }
303
304
305
306
307
308
309
310
311
312
313 public int indexOf(final Object object) {
314 return setOrder.indexOf(object);
315 }
316
317 @Override
318 public OrderedIterator<E> iterator() {
319 return new OrderedSetIterator<>(setOrder.listIterator(), decorated());
320 }
321
322
323
324
325
326
327
328
329
330 public E remove(final int index) {
331 final E obj = setOrder.remove(index);
332 remove(obj);
333 return obj;
334 }
335
336 @Override
337 public boolean remove(final Object object) {
338 final boolean result = decorated().remove(object);
339 if (result) {
340 setOrder.remove(object);
341 }
342 return result;
343 }
344
345 @Override
346 public boolean removeAll(final Collection<?> coll) {
347 boolean result = false;
348 for (final Object name : coll) {
349 result |= remove(name);
350 }
351 return result;
352 }
353
354
355
356
357 @Override
358 public boolean removeIf(final Predicate<? super E> filter) {
359 if (Objects.isNull(filter)) {
360 return false;
361 }
362 final boolean result = decorated().removeIf(filter);
363 if (result) {
364 setOrder.removeIf(filter);
365 }
366 return result;
367 }
368
369
370
371
372
373
374
375
376
377
378
379 @Override
380 public boolean retainAll(final Collection<?> coll) {
381 final boolean result = decorated().retainAll(coll);
382 if (!result) {
383 return false;
384 }
385 if (decorated().isEmpty()) {
386 setOrder.clear();
387 } else {
388 setOrder.removeIf(e -> !decorated().contains(e));
389 }
390 return result;
391 }
392
393 @Override
394 public Object[] toArray() {
395 return setOrder.toArray();
396 }
397
398 @Override
399 public <T> T[] toArray(final T[] a) {
400 return setOrder.toArray(a);
401 }
402
403
404
405
406
407
408
409
410
411 @Override
412 public String toString() {
413 return setOrder.toString();
414 }
415
416 }