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 }