// We want to "throw" Java exceptions in our code, // so we must import them first: import java.util.NoSuchElementException; import java.util.*; /********************************************************** A Generic Linked List class with a private static inner Node class. *********************************************************/ // make class name of generic type public class SimpleIterableLinkedList implements SimpleList, Iterable { /******************************************************* The private inner (nested) class "Node" ******************************************************* */ // make Node class name of generic type private class Node { // Node instance variable is generic private T item; private Node next; // parameters in constructor generic public Node(T item, Node next) { this.item = item; this.next = next; } public String toString(){ return "" + this.item; } } // End of private inner class "Node" /********************************************************/ // SimpleLinkedList instance variable "first" is declared of // type "Node", i.e. the inner class defined above // first is generic node private Node first; // Constructs an empty list public SimpleIterableLinkedList() { first = null; } // Returns true if the list is empty public boolean isEmpty() { return first==null; } // Inserts a new node at the beginning of this list // take in generic item; Nodes are generic public void addFirst(T item) { Node newNode = new Node(item, first); first = newNode; } // Inserts a new node to the end of this list // take in generic item; Nodes are generic public void addLast(T item) { if(isEmpty()) { first = new Node(item,null); //equivalent: addFirst(item) } else { Node current = first; while(current.next!=null) { current = current.next; } current.next = new Node(item,null); } } // Returns the first element (item) in the list // returns generic type public T getFirst() { if(isEmpty()) { throw new NoSuchElementException(); } return first.item; } // Returns the last element (item) in the list // returns generic type; Nodes are generic public T getLast() { if(isEmpty()) { throw new NoSuchElementException(); } Node current = first; while(current.next!=null) { current = current.next; } return current.item; } // Returns the item at the specified position in the list. // Note: Assume that pos is the index of the node, and that // node indexes start at zero! // returns generic type; Nodes are generic public T get(int pos) { // Coding strategy: Start by solving the general case, then add checks // for edge cases (e.g. What if "pos" is out-of-bound?) if(isEmpty()) { // empty list throw new NoSuchElementException(); } int i = 0; Node current = first; while(i current = first; Node previous = first; while(current!=null && !current.item.equals(key)) { previous = current; current = current.next; } if(current==null) { // key not found throw new NoSuchElementException(); } previous.next = current.next; } } // Reverse the linked list! // Example LL before reversing: // A => B => C => D => NULL // Example LL after reversing: // D => C => B => A => NULL // Nodes are generic /* ======================================================= Algorithm: current | V A -> B -> ... Read current A, B, C ... Insert the element at first location in new list ========================================================= */ public void reverse() { Node current = first; first = null; while(current!=null) { addFirst(current.item); current = current.next; } } /* public void reverse() { if(isEmpty()) { throw new NoSuchElementException(); } Node current1 = first; // iterate through old list in old order Node current2 = first; // iterate through new list to make new links while(current1.next != null) { Node newNode = new Node(current1.next.item, current2); current2 = newNode; current1 = current1.next; } first.next = null; first = current2; } */ // Returns a string representation public String toString() { String output = ""; if(first == null) throw new NoSuchElementException(); Node tmp = first; while(tmp != null) { output += tmp + " -> "; tmp = tmp.next; } output += "[NULL]"; return output; } /*******************************************************/ // Since our MyLinkedList implements the interface Iterable, // it must implement the abstract method iterator() /*******************************************************/ public Iterator iterator() { return new MyLinkedListIterator(); // See definition of MyLinkedListIterator class below } /******************************************************* * Private inner (nested) class MyLinkedListIterator * that implements the Java interface "Iterator" ********************************************************/ private class MyLinkedListIterator implements Iterator { private Node nextNode; // Remember the current node (unprocessed) // Constructor public MyLinkedListIterator() { nextNode = first; // the current node is the frst node } // Test if there is an unprcessed node public boolean hasNext() { return nextNode != null; // we aren't at the last node } // next() returns the content of the current node and // MOVES to the next (unprocessed) node public T next() { if (!hasNext()) { throw new NoSuchElementException(); } T res = nextNode.item; // get item at current position nextNode = nextNode.next; // move to the next node return res; } // We must implement remove() but we don't want to support // removal via Iterator objects, we only support removal via // the remove() method defined in MyLinkedList class above public void remove() { throw new UnsupportedOperationException(); } } // End of private inner class "MyLinkedListIterator" /********************************************************/ // TESTING public static void main(String[]args) { SimpleIterableLinkedList list = new SimpleIterableLinkedList(); list.addLast("A"); list.addLast("B"); list.addLast("C"); list.addLast("D"); // this one calls the toString method in SimpleIterableLinkedList System.out.println(list); System.out.println(); // implementing iterable we can use the iterator we defined Iterator itr = list.iterator(); while(itr.hasNext()) { System.out.println(itr.next()); } System.out.println(); // we can also use the for each loop for(String item : list) { System.out.println(item); } } } // End of class