1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.list;
18
19 import java.io.IOException;
20 import java.io.ObjectInputStream;
21 import java.io.ObjectOutputStream;
22 import java.lang.reflect.Array;
23 import java.util.AbstractList;
24 import java.util.Collection;
25 import java.util.ConcurrentModificationException;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.ListIterator;
29 import java.util.NoSuchElementException;
30 import java.util.Objects;
31
32 import org.apache.commons.collections4.CollectionUtils;
33 import org.apache.commons.collections4.OrderedIterator;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public abstract class AbstractLinkedListJava21<E> implements List<E> {
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 protected static class LinkedListIterator<E> implements ListIterator<E>, OrderedIterator<E> {
71
72
73 protected final AbstractLinkedListJava21<E> parent;
74
75
76
77
78
79 protected Node<E> next;
80
81
82
83
84 protected int nextIndex;
85
86
87
88
89
90
91
92
93
94 protected Node<E> current;
95
96
97
98
99
100
101
102 protected int expectedModCount;
103
104
105
106
107
108
109
110
111 protected LinkedListIterator(final AbstractLinkedListJava21<E> parent, final int fromIndex)
112 throws IndexOutOfBoundsException {
113 this.parent = parent;
114 this.expectedModCount = parent.modCount;
115 this.next = parent.getNode(fromIndex, true);
116 this.nextIndex = fromIndex;
117 }
118
119 @Override
120 public void add(final E obj) {
121 checkModCount();
122 parent.addNodeBefore(next, obj);
123 current = null;
124 nextIndex++;
125 expectedModCount++;
126 }
127
128
129
130
131
132
133
134
135 protected void checkModCount() {
136 if (parent.modCount != expectedModCount) {
137 throw new ConcurrentModificationException();
138 }
139 }
140
141
142
143
144
145
146
147
148 protected Node<E> getLastNodeReturned() throws IllegalStateException {
149 if (current == null) {
150 throw new IllegalStateException();
151 }
152 return current;
153 }
154
155 @Override
156 public boolean hasNext() {
157 return next != parent.header;
158 }
159
160 @Override
161 public boolean hasPrevious() {
162 return next.previous != parent.header;
163 }
164
165 @Override
166 public E next() {
167 checkModCount();
168 if (!hasNext()) {
169 throw new NoSuchElementException("No element at index " + nextIndex + ".");
170 }
171 final E value = next.getValue();
172 current = next;
173 next = next.next;
174 nextIndex++;
175 return value;
176 }
177
178 @Override
179 public int nextIndex() {
180 return nextIndex;
181 }
182
183 @Override
184 public E previous() {
185 checkModCount();
186 if (!hasPrevious()) {
187 throw new NoSuchElementException("Already at start of list.");
188 }
189 next = next.previous;
190 final E value = next.getValue();
191 current = next;
192 nextIndex--;
193 return value;
194 }
195
196 @Override
197 public int previousIndex() {
198
199 return nextIndex() - 1;
200 }
201
202 @Override
203 public void remove() {
204 checkModCount();
205 if (current == next) {
206
207 next = next.next;
208 parent.removeNode(getLastNodeReturned());
209 } else {
210
211 parent.removeNode(getLastNodeReturned());
212 nextIndex--;
213 }
214 current = null;
215 expectedModCount++;
216 }
217
218 @Override
219 public void set(final E obj) {
220 checkModCount();
221 getLastNodeReturned().setValue(obj);
222 }
223
224 }
225
226
227
228
229
230
231 protected static class LinkedSubList<E> extends AbstractList<E> {
232
233 AbstractLinkedListJava21<E> parent;
234
235 int offset;
236
237 int size;
238
239 int expectedModCount;
240
241
242
243
244
245
246
247
248 protected LinkedSubList(final AbstractLinkedListJava21<E> parent, final int fromIndex, final int toIndex) {
249 if (fromIndex < 0) {
250 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
251 }
252 if (toIndex > parent.size()) {
253 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
254 }
255 if (fromIndex > toIndex) {
256 throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
257 }
258 this.parent = parent;
259 this.offset = fromIndex;
260 this.size = toIndex - fromIndex;
261 this.expectedModCount = parent.modCount;
262 }
263
264 @Override
265 public void add(final int index, final E obj) {
266 rangeCheck(index, size + 1);
267 checkModCount();
268 parent.add(index + offset, obj);
269 expectedModCount = parent.modCount;
270 size++;
271 modCount++;
272 }
273
274 @Override
275 public boolean addAll(final Collection<? extends E> coll) {
276 return addAll(size, coll);
277 }
278
279 @Override
280 public boolean addAll(final int index, final Collection<? extends E> coll) {
281 rangeCheck(index, size + 1);
282 final int cSize = coll.size();
283 if (cSize == 0) {
284 return false;
285 }
286
287 checkModCount();
288 parent.addAll(offset + index, coll);
289 expectedModCount = parent.modCount;
290 size += cSize;
291 modCount++;
292 return true;
293 }
294
295
296
297
298 protected void checkModCount() {
299 if (parent.modCount != expectedModCount) {
300 throw new ConcurrentModificationException();
301 }
302 }
303
304 @Override
305 public void clear() {
306 checkModCount();
307 final Iterator<E> it = iterator();
308 while (it.hasNext()) {
309 it.next();
310 it.remove();
311 }
312 }
313
314 @Override
315 public E get(final int index) {
316 rangeCheck(index, size);
317 checkModCount();
318 return parent.get(index + offset);
319 }
320
321 @Override
322 public Iterator<E> iterator() {
323 checkModCount();
324 return parent.createSubListIterator(this);
325 }
326
327 @Override
328 public ListIterator<E> listIterator(final int index) {
329 rangeCheck(index, size + 1);
330 checkModCount();
331 return parent.createSubListListIterator(this, index);
332 }
333
334
335
336
337
338
339
340 protected void rangeCheck(final int index, final int beyond) {
341 if (index < 0 || index >= beyond) {
342 throw new IndexOutOfBoundsException("Index '" + index + "' out of bounds for size '" + size + "'");
343 }
344 }
345
346 @Override
347 public E remove(final int index) {
348 rangeCheck(index, size);
349 checkModCount();
350 final E result = parent.remove(index + offset);
351 expectedModCount = parent.modCount;
352 size--;
353 modCount++;
354 return result;
355 }
356
357 @Override
358 public E set(final int index, final E obj) {
359 rangeCheck(index, size);
360 checkModCount();
361 return parent.set(index + offset, obj);
362 }
363
364 @Override
365 public int size() {
366 checkModCount();
367 return size;
368 }
369
370 @Override
371 public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
372 return new LinkedSubList<>(parent, fromIndexInclusive + offset, toIndexExclusive + offset);
373 }
374 }
375
376
377
378
379
380
381 protected static class LinkedSubListIterator<E> extends LinkedListIterator<E> {
382
383
384 protected final LinkedSubList<E> sub;
385
386
387
388
389
390
391
392 protected LinkedSubListIterator(final LinkedSubList<E> sub, final int startIndex) {
393 super(sub.parent, startIndex + sub.offset);
394 this.sub = sub;
395 }
396
397 @Override
398 public void add(final E obj) {
399 super.add(obj);
400 sub.expectedModCount = parent.modCount;
401 sub.size++;
402 }
403
404 @Override
405 public boolean hasNext() {
406 return nextIndex() < sub.size;
407 }
408
409 @Override
410 public boolean hasPrevious() {
411 return previousIndex() >= 0;
412 }
413
414 @Override
415 public int nextIndex() {
416 return super.nextIndex() - sub.offset;
417 }
418
419 @Override
420 public void remove() {
421 super.remove();
422 sub.expectedModCount = parent.modCount;
423 sub.size--;
424 }
425 }
426
427
428
429
430
431
432
433
434
435
436 protected static class Node<E> {
437
438
439 protected Node<E> previous;
440
441 protected Node<E> next;
442
443 protected E value;
444
445
446
447
448 protected Node() {
449 previous = this;
450 next = this;
451 }
452
453
454
455
456
457
458 protected Node(final E value) {
459 this.value = value;
460 }
461
462
463
464
465
466
467
468
469 protected Node(final Node<E> previous, final Node<E> next, final E value) {
470 this.previous = previous;
471 this.next = next;
472 this.value = value;
473 }
474
475
476
477
478
479
480
481 protected Node<E> getNextNode() {
482 return next;
483 }
484
485
486
487
488
489
490
491 protected Node<E> getPreviousNode() {
492 return previous;
493 }
494
495
496
497
498
499
500
501 protected E getValue() {
502 return value;
503 }
504
505
506
507
508
509
510
511 protected void setNextNode(final Node<E> next) {
512 this.next = next;
513 }
514
515
516
517
518
519
520
521 protected void setPreviousNode(final Node<E> previous) {
522 this.previous = previous;
523 }
524
525
526
527
528
529
530
531 protected void setValue(final E value) {
532 this.value = value;
533 }
534 }
535
536
537
538
539
540
541 transient Node<E> header;
542
543
544 transient int size;
545
546
547 transient int modCount;
548
549
550
551
552
553
554
555 protected AbstractLinkedListJava21() {
556 }
557
558
559
560
561
562
563 protected AbstractLinkedListJava21(final Collection<? extends E> coll) {
564 init();
565 addAll(coll);
566 }
567
568 @Override
569 public boolean add(final E value) {
570 addLast(value);
571 return true;
572 }
573
574 @Override
575 public void add(final int index, final E value) {
576 final Node<E> node = getNode(index, true);
577 addNodeBefore(node, value);
578 }
579
580 @Override
581 public boolean addAll(final Collection<? extends E> coll) {
582 return addAll(size, coll);
583 }
584
585 @Override
586 public boolean addAll(final int index, final Collection<? extends E> coll) {
587 final Node<E> node = getNode(index, true);
588 for (final E e : coll) {
589 addNodeBefore(node, e);
590 }
591 return true;
592 }
593
594
595
596
597 public void addFirst(final E o) {
598 addNodeAfter(header, o);
599 }
600
601
602
603
604 public void addLast(final E o) {
605 addNodeBefore(header, o);
606 }
607
608
609
610
611
612
613
614
615 protected void addNode(final Node<E> nodeToInsert, final Node<E> insertBeforeNode) {
616 Objects.requireNonNull(nodeToInsert, "nodeToInsert");
617 Objects.requireNonNull(insertBeforeNode, "insertBeforeNode");
618 nodeToInsert.next = insertBeforeNode;
619 nodeToInsert.previous = insertBeforeNode.previous;
620 insertBeforeNode.previous.next = nodeToInsert;
621 insertBeforeNode.previous = nodeToInsert;
622 size++;
623 modCount++;
624 }
625
626
627
628
629
630
631
632
633
634
635
636
637 protected void addNodeAfter(final Node<E> node, final E value) {
638 final Node<E> newNode = createNode(value);
639 addNode(newNode, node.next);
640 }
641
642
643
644
645
646
647
648
649
650
651
652
653 protected void addNodeBefore(final Node<E> node, final E value) {
654 final Node<E> newNode = createNode(value);
655 addNode(newNode, node);
656 }
657
658 @Override
659 public void clear() {
660 removeAllNodes();
661 }
662
663 @Override
664 public boolean contains(final Object value) {
665 return indexOf(value) != -1;
666 }
667
668 @Override
669 public boolean containsAll(final Collection<?> coll) {
670 for (final Object o : coll) {
671 if (!contains(o)) {
672 return false;
673 }
674 }
675 return true;
676 }
677
678
679
680
681
682
683
684
685 protected Node<E> createHeaderNode() {
686 return new Node<>();
687 }
688
689
690
691
692
693
694
695
696
697 protected Node<E> createNode(final E value) {
698 return new Node<>(value);
699 }
700
701
702
703
704
705
706
707 protected Iterator<E> createSubListIterator(final LinkedSubList<E> subList) {
708 return createSubListListIterator(subList, 0);
709 }
710
711
712
713
714
715
716
717
718 protected ListIterator<E> createSubListListIterator(final LinkedSubList<E> subList, final int fromIndex) {
719 return new LinkedSubListIterator<>(subList, fromIndex);
720 }
721
722
723
724
725
726
727
728
729
730
731
732 @SuppressWarnings("unchecked")
733 protected void doReadObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
734 init();
735 final int size = inputStream.readInt();
736 for (int i = 0; i < size; i++) {
737 add((E) inputStream.readObject());
738 }
739 }
740
741
742
743
744
745
746
747
748
749
750 protected void doWriteObject(final ObjectOutputStream outputStream) throws IOException {
751
752 outputStream.writeInt(size());
753 for (final E e : this) {
754 outputStream.writeObject(e);
755 }
756 }
757
758 @Override
759 public boolean equals(final Object obj) {
760 if (obj == this) {
761 return true;
762 }
763 if (!(obj instanceof List)) {
764 return false;
765 }
766 final List<?> other = (List<?>) obj;
767 if (other.size() != size()) {
768 return false;
769 }
770 final ListIterator<?> it1 = listIterator();
771 final ListIterator<?> it2 = other.listIterator();
772 while (it1.hasNext() && it2.hasNext()) {
773 if (!Objects.equals(it1.next(), it2.next())) {
774 return false;
775 }
776 }
777 return !(it1.hasNext() || it2.hasNext());
778 }
779
780 @Override
781 public E get(final int index) {
782 final Node<E> node = getNode(index, false);
783 return node.getValue();
784 }
785
786
787
788
789 public E getFirst() {
790 final Node<E> node = header.next;
791 if (node == header) {
792 throw new NoSuchElementException();
793 }
794 return node.getValue();
795 }
796
797
798
799
800 public E getLast() {
801 final Node<E> node = header.previous;
802 if (node == header) {
803 throw new NoSuchElementException();
804 }
805 return node.getValue();
806 }
807
808
809
810
811
812
813
814
815
816
817
818
819 protected Node<E> getNode(final int index, final boolean endMarkerAllowed) throws IndexOutOfBoundsException {
820
821 if (index < 0) {
822 throw new IndexOutOfBoundsException("Couldn't get the node: " +
823 "index (" + index + ") less than zero.");
824 }
825 if (!endMarkerAllowed && index == size) {
826 throw new IndexOutOfBoundsException("Couldn't get the node: " +
827 "index (" + index + ") is the size of the list.");
828 }
829 if (index > size) {
830 throw new IndexOutOfBoundsException("Couldn't get the node: " +
831 "index (" + index + ") greater than the size of the " +
832 "list (" + size + ").");
833 }
834
835 Node<E> node;
836 if (index < size / 2) {
837
838 node = header.next;
839 for (int currentIndex = 0; currentIndex < index; currentIndex++) {
840 node = node.next;
841 }
842 } else {
843
844 node = header;
845 for (int currentIndex = size; currentIndex > index; currentIndex--) {
846 node = node.previous;
847 }
848 }
849 return node;
850 }
851
852 @Override
853 public int hashCode() {
854 int hashCode = 1;
855 for (final E e : this) {
856 hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
857 }
858 return hashCode;
859 }
860
861 @Override
862 public int indexOf(final Object value) {
863 int i = 0;
864 for (Node<E> node = header.next; node != header; node = node.next) {
865 if (isEqualValue(node.getValue(), value)) {
866 return i;
867 }
868 i++;
869 }
870 return CollectionUtils.INDEX_NOT_FOUND;
871 }
872
873
874
875
876
877
878
879 protected void init() {
880 header = createHeaderNode();
881 }
882
883 @Override
884 public boolean isEmpty() {
885 return size() == 0;
886 }
887
888
889
890
891
892
893
894
895
896
897 protected boolean isEqualValue(final Object value1, final Object value2) {
898 return Objects.equals(value1, value2);
899 }
900
901 @Override
902 public Iterator<E> iterator() {
903 return listIterator();
904 }
905
906 @Override
907 public int lastIndexOf(final Object value) {
908 int i = size - 1;
909 for (Node<E> node = header.previous; node != header; node = node.previous) {
910 if (isEqualValue(node.getValue(), value)) {
911 return i;
912 }
913 i--;
914 }
915 return CollectionUtils.INDEX_NOT_FOUND;
916 }
917
918 @Override
919 public ListIterator<E> listIterator() {
920 return new LinkedListIterator<>(this, 0);
921 }
922
923 @Override
924 public ListIterator<E> listIterator(final int fromIndex) {
925 return new LinkedListIterator<>(this, fromIndex);
926 }
927
928 @Override
929 public E remove(final int index) {
930 final Node<E> node = getNode(index, false);
931 final E oldValue = node.getValue();
932 removeNode(node);
933 return oldValue;
934 }
935
936 @Override
937 public boolean remove(final Object value) {
938 for (Node<E> node = header.next; node != header; node = node.next) {
939 if (isEqualValue(node.getValue(), value)) {
940 removeNode(node);
941 return true;
942 }
943 }
944 return false;
945 }
946
947
948
949
950
951
952
953
954
955
956 @Override
957 public boolean removeAll(final Collection<?> coll) {
958 boolean modified = false;
959 final Iterator<E> it = iterator();
960 while (it.hasNext()) {
961 if (coll.contains(it.next())) {
962 it.remove();
963 modified = true;
964 }
965 }
966 return modified;
967 }
968
969
970
971
972 protected void removeAllNodes() {
973 header.next = header;
974 header.previous = header;
975 size = 0;
976 modCount++;
977 }
978
979
980
981
982 public E removeFirst() {
983 final Node<E> node = header.next;
984 if (node == header) {
985 throw new NoSuchElementException();
986 }
987 final E oldValue = node.getValue();
988 removeNode(node);
989 return oldValue;
990 }
991
992
993
994
995 public E removeLast() {
996 final Node<E> node = header.previous;
997 if (node == header) {
998 throw new NoSuchElementException();
999 }
1000 final E oldValue = node.getValue();
1001 removeNode(node);
1002 return oldValue;
1003 }
1004
1005
1006
1007
1008
1009
1010
1011 protected void removeNode(final Node<E> node) {
1012 Objects.requireNonNull(node, "node");
1013 node.previous.next = node.next;
1014 node.next.previous = node.previous;
1015 size--;
1016 modCount++;
1017 }
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 @Override
1029 public boolean retainAll(final Collection<?> coll) {
1030 boolean modified = false;
1031 final Iterator<E> it = iterator();
1032 while (it.hasNext()) {
1033 if (!coll.contains(it.next())) {
1034 it.remove();
1035 modified = true;
1036 }
1037 }
1038 return modified;
1039 }
1040
1041 @Override
1042 public E set(final int index, final E value) {
1043 final Node<E> node = getNode(index, false);
1044 final E oldValue = node.getValue();
1045 updateNode(node, value);
1046 return oldValue;
1047 }
1048
1049 @Override
1050 public int size() {
1051 return size;
1052 }
1053
1054
1055
1056
1057
1058
1059
1060
1061 @Override
1062 public List<E> subList(final int fromIndexInclusive, final int toIndexExclusive) {
1063 return new LinkedSubList<>(this, fromIndexInclusive, toIndexExclusive);
1064 }
1065
1066 @Override
1067 public Object[] toArray() {
1068 return toArray(new Object[size]);
1069 }
1070
1071 @Override
1072 @SuppressWarnings("unchecked")
1073 public <T> T[] toArray(T[] array) {
1074
1075 if (array.length < size) {
1076 final Class<?> componentType = array.getClass().getComponentType();
1077 array = (T[]) Array.newInstance(componentType, size);
1078 }
1079
1080 int i = 0;
1081 for (Node<E> node = header.next; node != header; node = node.next, i++) {
1082 array[i] = (T) node.getValue();
1083 }
1084
1085 if (array.length > size) {
1086 array[size] = null;
1087 }
1088 return array;
1089 }
1090
1091 @Override
1092 public String toString() {
1093 if (isEmpty()) {
1094 return "[]";
1095 }
1096 final StringBuilder buf = new StringBuilder(16 * size());
1097 buf.append(CollectionUtils.DEFAULT_TOSTRING_PREFIX);
1098
1099 final Iterator<E> it = iterator();
1100 boolean hasNext = it.hasNext();
1101 while (hasNext) {
1102 final Object value = it.next();
1103 buf.append(value == this ? "(this Collection)" : value);
1104 hasNext = it.hasNext();
1105 if (hasNext) {
1106 buf.append(", ");
1107 }
1108 }
1109 buf.append(CollectionUtils.DEFAULT_TOSTRING_SUFFIX);
1110 return buf.toString();
1111 }
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121 protected void updateNode(final Node<E> node, final E value) {
1122 node.setValue(value);
1123 }
1124
1125 }