import java.util.NoSuchElementException; /** * A generic LinkedList implementation. */ public class LinkedList> implements LinkedListInterface { /** * The node class. Each element in the linked list is an instance of Node */ private class Node> { /** The data item in the node. */ public Comparable data; /** The next item in the linked list */ public Node next; /** * Node constructor. Takes a rannit and another node */ public Node(Comparable data, Node next) { this.data = data; this.next = next; } } /** The start, first element, of the linked list */ private Node head = null; /** THe last element in the linked list */ private Node tail = null; /** The number of items in the linked list */ private int size = 0; /** * The number of items in the linked list * * @return the number of items in the linked list */ @Override public int size() { return size; } /** * Returns true iff the linked list has no elements * * @return true iff the linked list has no elements */ @Override public boolean isEmpty() { return size == 0; } /** * Get the first element in the linked list * * @return the first element in the linked list * @throws NoSuchElementException is the list is empty */ @Override @SuppressWarnings("unchecked") public T first() throws NoSuchElementException { if (head == null) throw new NoSuchElementException("The list is empty"); return (T)head.data; } /** * The last element in the linked list * * @return the last elment * @throws NoSuchElementException if the linked list is empty */ @Override @SuppressWarnings("unchecked") public T last() throws NoSuchElementException { if (head == null) throw new NoSuchElementException("The list is empty"); return (T)tail.data; } /** * Add an element to the end of the list * * @param c the element to be added */ @Override public void addLast(T c) { Node newest = new Node<>(c, null); if (isEmpty()) { head = newest; } else { tail.next = newest; } tail = newest; size++; } /** * Add an element at the front of the list * * @param c the element to be added */ @Override public void addFirst(T c) { Node newest = new Node<>(c, null); if (isEmpty()) { head = newest; tail = newest; } else { newest.next = head; } head = newest; size++; } /** * Remove the first element from the list * * @return the first element, or null if the list is empty */ @Override @SuppressWarnings("unchecked") public T removeFirst() { if (head == null) return null; Comparable rtn = head.data; head = head.next; if (head == null) tail = null; return (T)rtn; } /** * Remove the last from the list * * @return the last element, or null if the list is empty */ @Override @SuppressWarnings("unchecked") public T removeLast() { if (head == null) return null; if (head == tail) { head = null; Comparable rtn = tail.data; size = 0; tail = null; return (T)rtn; } // start at front and get to the node prior to the last Node curr = head; while (curr.next != tail) { curr = curr.next; } Comparable rtn = tail.data; tail = curr; tail.next = null; size--; return (T)rtn; } /** * Remove the specified element from the list * * @param r the element to be removed * @return the removed element, or null is the element was not in the list */ @Override public T remove(T r) { // Do something much like find, but need to trak the previous node Node prev = null; Node curr = head; while (curr != null) { if (0==curr.data.compareTo(r)) { break; } prev = curr; curr = curr.next; } // three cases: if (curr == null) { // 1. the element was not found return null; } if (prev == null) { // 2. the element was the first item in the list size--; head = head.next; return r; } // 3. Element is somewhere it list // special -- element is at end of list size--; prev.next = curr.next; if (curr == tail) tail = prev; return r; } /** * Find an in the list (essentially determine if the element is in the list) * * @param iD * @return the found element, or null if a match could not be found */ @Override @SuppressWarnings("unchecked") public T find(T rr) { Node curr = head; while (curr != null) { if (0 == curr.data.compareTo(rr)) { return (T) curr.data; } curr = curr.next; } return null; } public String toString() { StringBuffer s = new StringBuffer(); for (Node n = head; n != null; n = n.next) { s.append(n.data.toString()); if (n != tail) { s.append("\n"); } } return s.toString(); } public static void main(String[] args) { LinkedList llr = new LinkedList<>(); Rabbit ar = new Rabbit(BreedEnum.Angora, "A1"); llr.addFirst(ar); llr.addFirst(new Rabbit(BreedEnum.DwarfDutch, "DD1")); llr.addLast(new Rabbit(BreedEnum.FrenchLop, "FL1")); System.out.println(llr); // llr.removeFirst(); // llr.removeLast(); llr.remove(ar); System.out.println(); System.out.println(llr); } }