1 package ch.hslu.exercises.sw02.ex2;
2
3 import org.jetbrains.annotations.Contract;
4 import org.jetbrains.annotations.NotNull;
5
6 import java.util.AbstractList;
7 import java.util.Iterator;
8
9 public final class MyLinkedList<T> extends AbstractList<T> {
10
11 private Node<T> head = null;
12
13 @Override
14 public boolean isEmpty() {
15 return head == null;
16 }
17
18 @SafeVarargs
19 public final void insertAtHead(final T... elements) {
20 for (T element : elements) {
21 insertAtHead(element);
22 }
23 }
24
25 private void insertAtHead(final T element) {
26 Node<T> newNode = new Node<>(element);
27 newNode.setNext(head);
28 head = newNode;
29 }
30
31 public T popElementAtHead() {
32 if (isEmpty()) {
33 throw new IllegalStateException("No head element on empty list.");
34 } else {
35 Node<T> oldHead = head;
36 removeHead();
37 return oldHead.getValue();
38 }
39 }
40
41
42 private void removeHead() {
43 head = head.getNext();
44 }
45
46 @Override
47 public int size() {
48 int i = 0;
49 for (T ignored : this) {
50 i++;
51 }
52 return i;
53 }
54
55
56 public T getHead() {
57 if (isEmpty()) {
58 throw new IllegalStateException("No head element on empty list.");
59 } else {
60 return head.getValue();
61 }
62 }
63
64 public void removeElement(final T elementToBeRemoved) {
65 if (head.getValue().equals(elementToBeRemoved)) {
66 removeHead();
67 return;
68 }
69 Node<T> temp = head, prev = null;
70 while (temp != null && temp.getValue() != elementToBeRemoved) {
71 prev = temp;
72 temp = temp.getNext();
73 }
74 if (temp == null) {
75 return;
76 }
77 prev.setNext(temp.getNext());
78 }
79
80
81 @Override
82 public T get(final int index) {
83 if (isEmpty()) {
84 throw new IllegalStateException("The List is empty");
85 }
86 int i = 0;
87 for (T element : this) {
88 if (i == index) {
89 return element;
90 }
91 i++;
92 }
93 return null;
94 }
95
96 @NotNull
97 @Contract(" -> new")
98 @Override
99 public Iterator<T> iterator() {
100 return new MyLinkedListIterator();
101 }
102
103
104 private final class MyLinkedListIterator implements Iterator<T> {
105 private Node<T> current = head;
106
107 @Override
108 public boolean hasNext() {
109 return current != null;
110 }
111
112 @Override
113 public T next() {
114 T data = current.getValue();
115 current = current.getNext();
116 return data;
117 }
118
119 }
120
121 private static final class Node<E> {
122 private final E value;
123 private Node<E> next;
124
125 Node(final E value) {
126 this.value = value;
127 }
128
129 public E getValue() {
130 return this.value;
131 }
132
133 public Node<E> getNext() {
134 return this.next;
135 }
136
137 public void setNext(final Node<E> next) {
138 this.next = next;
139 }
140 }
141 }