import java.util.NoSuchElementException; public class LinkedList> { private static class Node { private T value; private Node next; private Node(T value, Node next) { this.value = value; this.next = next; } } private Node head = null; private int size; public void addFirst(E element) { if (element == null) { throw new NullPointerException(); } head = new Node(element, head); size++; } public E get(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException(Integer.toString(size)); } return get(head, index); } private E get(Node current, int index) { if (index == 0) { return current.value; } return get(current.next, index-1); } public int indexOf(E element) { if (element == null) { throw new NullPointerException(); } return indexOf(head, element); } private int indexOf(Node current, E element) { if (current == null) { return -1; } int result = indexOf(current.next, element); if (current.value.equals(element)) { return 0; } if (result == -1) { return result; } return result + 1; } public int indexOfLast(E element) { if (element == null) { throw new NullPointerException(); } return indexOfLast(head, element); } private int indexOfLast(Node current, E element) { if (current == null) { return -1; } int result = indexOfLast(current.next, element); if (result > -1) { return result + 1; } else if (element.equals(current.value)) { return 0; } return -1; } public boolean isIncreasing() { return isIncreasing(head); } private boolean isIncreasing(Node current) { if ((current == null) || (current.next == null)) { return true; } if (current.value.compareTo(current.next.value) > 0 ) { return false; } return isIncreasing(current.next); } public boolean remove(E element) { if (element == null) { throw new NullPointerException("Illegal argument"); } if (head == null) { throw new NoSuchElementException(); } boolean result; if (head.value.equals(element) ) { head = head.next; result = true; } else { result = remove(head,element); } return result; } private boolean remove(Node current, E element) { if (current.next == null ) { return false; } boolean result; if (current.next.value.equals(element)) { current.next = current.next.next; result = true; } else { result = remove(current.next, element); // general case } return result; } public LinkedList subList1(int fromIndex, int toIndex) { return subList1(head, 0, fromIndex, toIndex); } private LinkedList subList1(Node current, int index, int fromIndex, int toIndex) { LinkedList result; if (index == toIndex) { result = new LinkedList(); result.addFirst(current.value); } else { result = subList1(current.next, index+1, fromIndex, toIndex); if (index >= fromIndex) { result.addFirst(current.value); } } return result; } public LinkedList subList2(int fromIndex, int toIndex) { LinkedList result = new LinkedList(); subList2(head, 0, result, fromIndex, toIndex); return result; } private void subList2(Node current, int index, LinkedList result, int fromIndex, int toIndex) { if (index == toIndex ) { result.addLast(current.value); } else { if (index >= fromIndex) { result.addLast(current.value); } subList2(current.next, index+1, result, fromIndex, toIndex); } } public void addLast(E element) { if (element == null) { throw new NullPointerException(); } if (head == null) { head = new Node(element, head); size++; } else { addLast(head, element); } } private void addLast(Node current, E element) { if (current.next == null) { current.next = new Node(element, null); size++; } else { addLast(current.next, element); } } public String toString() { String str = "["; if (head != null) { str += head.value; } return str + toString(head.next) + "]"; } private String toString(Node current) { if (current == null) { return ""; } else { return ", " + current.value + toString(current.next); } } public static void main(String[] args) { LinkedList xs = new LinkedList(); for (int i=4; i>=0; i--) { xs.addFirst(i); } System.out.println(xs); } }