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