package edu.basejava.util;
import java.util.Iterator;
public class LinkedList<E> implements IList<E>, Iterable<E>
{
private Link<E> head;
private Link<E> tail;
protected Link<E> curr;
public LinkedList()
{
this.setup();
}
LinkedList(E[] elements)
{
this.setup();
for (E e : elements)
this.append(e);
}
public void append(E item)
{
this.tail.setNext(new Link<E>(item, null));
this.tail = this.tail.next();
}
public void clear()
{
this.head.setNext(null);
this.curr = this.head = this.tail = null;
}
public E currValue()
{
if (!this.isInList())
{
System.err.println("Curr is not in the list");
return null;
}
return this.curr.next().element();
}
@SuppressWarnings("unchecked")
public void insert(E item)
{
if (this.curr == null)
{
System.err.println("No current element");
return;
}
this.curr.setNext(new Link<E>(item, this.curr.next()));
if (this.tail == this.curr)
{
this.tail = this.curr.next();
}
}
public boolean isEmpty()
{
return this.head.next() == null;
}
public boolean isInList()
{
return (this.curr != null) && (this.curr.next() != null);
}
public int length()
{
int cnt = 0;
for (Link<E> tmp = this.head.next(); tmp != null; tmp = tmp.next())
cnt++;
return cnt;
}
public boolean hasNext()
{
return this.curr != null;
}
public void next()
{
if (this.curr != null)
this.curr = this.curr.next();
}
public void prev()
{
if ((this.curr == null) || (this.curr == this.head))
{
this.curr = null;
return;
}
Link<E> tmp = this.head;
while ((tmp != null) && (tmp.next() != this.curr))
tmp = tmp.next();
this.curr = tmp;
}
public void print()
{
if (this.isEmpty())
System.out.println("()");
else
{
System.out.print("( ");
for (this.setFirst(); this.isInList(); this.next())
System.out.print(this.currValue() + " ");
System.out.println(")");
}
}
public E remove()
{
if (!this.isInList())
return null;
E it = this.curr.next().element();
if (this.tail == this.curr.next())
this.tail = this.curr;
this.curr.setNext(this.curr.next().next());
return it;
}
public void remove(E element)
{
for (this.setFirst(); this.isInList(); this.next())
if (this.currValue().equals(element))
{
this.curr.setNext(this.curr.next().next());
if (this.curr == this.tail)
{
this.curr.setNext(null);
this.tail = this.curr;
}
}
}
public void setFirst()
{
this.curr = this.head;
}
public void setPos(int pos)
{
this.curr = this.head;
for (int i = 0; (this.curr != null) && (i < pos); i++)
this.curr = this.curr.next();
}
public void setValue(E val)
{
if (!this.isInList())
{
System.err.println("Curr is not in the list");
return;
}
this.curr.next().setElement(val);
}
public String toString()
{
if (this.isEmpty())
return ("()");
StringBuffer sb = new StringBuffer();
sb.append("( ");
for (this.setFirst(); this.isInList(); this.next())
sb.append(this.currValue() + " ");
sb.append(")");
return sb.toString();
}
private void setup()
{
this.tail = this.head = this.curr = new Link<E>(null);
}
@SuppressWarnings("hiding")
private class Link<E>
{
private E element;
private Link<E> next;
Link(E element, Link<E> next)
{
this.element = element;
this.next = next;
}
Link(Link<E> next)
{
this.next = next;
}
public E element()
{
return element;
}
public void setElement(E element)
{
this.element = element;
}
public Link<E> next()
{
return next;
}
public void setNext(Link<E> next)
{
this.next = next;
}
}
public Iterator<E> iterator()
{
return new Ite();
}
private class Ite implements Iterator<E>
{
Ite()
{
LinkedList.this.setFirst();
}
public void remove()
{
throw new UnsupportedOperationException();
}
public boolean hasNext()
{
LinkedList.this.next();
return LinkedList.this.hasNext();
}
public E next()
{
return curr.element();
}
}
}