

public class LinkedListOfEmployees implements Cloneable
{
    private class Node
    {
        private Employee data;
        private Node link;

        public Node( )
        {
             data = null;
             link = null;
        }

        public Node(Employee newData, Node linkValue)
        {
            data = newData;
            link = linkValue;
        }
     }//End of Node inner class


    private Node head;

    public LinkedListOfEmployees( )
    {
        head = null;
    }

    /**
     Throws a NullPointerException if other is null. Produces a completely
     independent copy with no referenes in common with otherList
    */
    public LinkedListOfEmployees(LinkedListOfEmployees otherList)
    {
         if (otherList == null)
             throw new NullPointerException( );
         if (otherList.head == null)
             head = null;
         else
             head = copyOf(otherList.head);
    }

    //Precondition: otherHead != null
    //Returns a reference to the head of a copy of the
    //list headed by otherHead. Does a deep copy.
    private Node copyOf(Node otherHead)
    {
        Node position = otherHead;//moves down other’s list.
        Node newHead; //will point to head of the copy list.
        Node end = null; //positioned at end of new growing list.
        //Create first node:
        newHead =
              new Node((Employee)((position.data).clone( )), null);
        end = newHead;
        position = position.link;

        while (position != null)
        {//copy node at position to end of new list.
            end.link =
                new Node((Employee)((position.data).clone( )), null);
            end = end.link;
            position = position.link;
        }

        return newHead;
    }

    public Object clone( )
    {
        try
        {
            LinkedListOfEmployees copy =
                              (LinkedListOfEmployees)super.clone( );
            copy.head = copyOf(this.head);
            return copy;
        }
        catch(CloneNotSupportedException e)
        {//This should not happen.
            return null; //To keep the compiler happy.
        }
    }

    /**
     Adds a node at the head of the list with the newData.
    */
    public void add(Employee newData)
    {
        head = new Node(newData, head);
    }

    /**
     Removes the head node and returns true if the list contains at least
     one node. Returns false if the list is empty.
    */
    public boolean deleteHeadNode( )
    {
        if (head != null)
        {
            head = head.link;
            return true;
        }
        else
            return false;
    }

    /**
     Returns the number of nodes in the list.
    */
    public int size( )
    {
        int count = 0;
        Node position = head;
        while (position != null)
        {
            count++;
            position = position.link;
        }
        return count;
    }

    public boolean contains(Employee target)
    {
        return (find(target) != null);
    }

    /**
     Finds the first node containing the target item, and returns a
     reference to that node. If target is not in the list, null is returned.
    */
    private Node find(Employee target)
    {
        Node position = head;
        Employee dataAtPosition;
        while (position != null)
        {
            dataAtPosition = position.data;
            if (target.equals(dataAtPosition))
                return position;
            position = position.link;
        }
        return null; //target was not found
    }

    public boolean isEmpty( )
    {
        return (head == null);
    }

    public void clear( )
    {
        head = null;
    }

    public boolean equals(Object otherList)
    {
        if (otherList == null)
            return false;
        else if (getClass( ) != otherList.getClass( ))
            return false;
        else if (size( ) != ((LinkedListOfEmployees)otherList).size( ))
            return false;
        else
            return compareLists((LinkedListOfEmployees)otherList);
    }

    //Precondition: size( ) == otherList.size( ).
    //Returns true if node by node, objects are equal.
    private boolean compareLists(LinkedListOfEmployees otherList)
    {
        boolean match = true;//so far
        Node position = head;
        Node otherPosition = otherList.head;

        while (match && position != null)
        {
              if (!position.equals(otherPosition))
                  match = false;
              position = position.link;
              otherPosition = otherPosition.link;
        }
        return match;
    }

    public void outputList( )
    {
        Node position = head;
        while (position != null)
        {
            System.out.println(position.data);
            position = position.link;
        }
    }

}




