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