MyLinkedList.java
package ch.hslu.exercises.sw02.ex2;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.AbstractList;
import java.util.Iterator;
public final class MyLinkedList<T> extends AbstractList<T> {
private Node<T> head = null;
@Override
public boolean isEmpty() {
return head == null;
}
@SafeVarargs
public final void insertAtHead(final T... elements) {
for (T element : elements) {
insertAtHead(element);
}
}
private void insertAtHead(final T element) {
Node<T> newNode = new Node<>(element);
newNode.setNext(head);
head = newNode;
}
public T popElementAtHead() {
if (isEmpty()) {
throw new IllegalStateException("No head element on empty list.");
} else {
Node<T> oldHead = head;
removeHead();
return oldHead.getValue();
}
}
private void removeHead() {
head = head.getNext();
}
@Override
public int size() {
int i = 0;
for (T ignored : this) {
i++;
}
return i;
}
public T getHead() {
if (isEmpty()) {
throw new IllegalStateException("No head element on empty list.");
} else {
return head.getValue();
}
}
public void removeElement(final T elementToBeRemoved) {
if (head.getValue().equals(elementToBeRemoved)) {
removeHead();
return;
}
Node<T> temp = head, prev = null;
while (temp != null && temp.getValue() != elementToBeRemoved) {
prev = temp;
temp = temp.getNext();
}
if (temp == null) {
return;
}
prev.setNext(temp.getNext());
}
@Override
public T get(final int index) {
if (isEmpty()) {
throw new IllegalStateException("The List is empty");
}
int i = 0;
for (T element : this) {
if (i == index) {
return element;
}
i++;
}
return null;
}
@NotNull
@Contract(" -> new")
@Override
public Iterator<T> iterator() {
return new MyLinkedListIterator();
}
private final class MyLinkedListIterator implements Iterator<T> {
private Node<T> current = head;
@Override
public boolean hasNext() {
return current != null;
}
@Override
public T next() {
T data = current.getValue();
current = current.getNext();
return data;
}
}
private static final class Node<E> {
private final E value;
private Node<E> next;
Node(final E value) {
this.value = value;
}
public E getValue() {
return this.value;
}
public Node<E> getNext() {
return this.next;
}
public void setNext(final Node<E> next) {
this.next = next;
}
}
}