
public class YourLinkedList<E> {

	private class Node {
		E data;
		Node next;
		
		private Node(E item) {
			data = item;
			next = null;
		}
		
		private Node() {
			this(null);
		}
	}
	
	Node Head, Tail;
	int size;
	
	public YourLinkedList() {
		Head = new Node();
		Tail = Head;
		size = 0;
	}
	
	public void add(E item) {
		Node p = new Node(item);
		Tail.next = p;
		Tail = p;
		size += 1;
	}
	
	public E get(int i) throws IndexOutOfBoundsException {
		if (i < 0 || i >= size)
			throw new IndexOutOfBoundsException( "bad index in get");
		else {
			Node p = Head.next;
			for (int k = 0; k < i; k++)
				p = p.next;
			return p.data;
		}
	}
	
	public void add(int i, E item)throws IndexOutOfBoundsException {
		if (i < 0 || i > size)
			throw new IndexOutOfBoundsException( "bad index in add");
		else {
			Node p = Head;
			for (int k = 0; k < i; k++) 
				p = p.next;
			Node q = new Node(item);
			q.next = p.next;
			p.next = q;
			size += 1;
		}	
	}
	
	public void delete(int i) throws IndexOutOfBoundsException {
		if (i < 0 || i >= size)
			throw new IndexOutOfBoundsException( "bad index in add");
		else {
			Node p = Head;
			for (int k = 0; k < i; k++) 
				p = p.next;	// stops before the node to delete
			Node q = p.next;
			if (q == Tail)
				Tail = p;
			else
				p.next = q.next;
			size -= 1;
		}
	}
	
	public int size() {
		return size;
	}

}
