title: Generic Linked List of Objects (Java)
body: <p>I'm pretty new to Java, with this being my second class (in College) using it. Towards the beginning of the semester, I made a simple class representing Zombies that holds their age, type, and name. Later on, I made a linked list of integers. Now, I need to make a generic linked list that can hold these 'Zombies'. I also have to make a menu that allows me to add, remove, count, and display 'Zombies'. I've been staring at this for hours, going through my book, and looking online for the answer to my problem. I can add and display these 'Zombies', but counting them in the list and trying to remove them simply has it tell me there's none with the parameters I entered. In other words, there might be a problem with how I compare the 'Zombies'. Here's my code. I understand it's a good 300 lines of code to look through... but i'm out of ideas.</p>
  
  <p>Zombie.java</p>
  
  <pre><code>public class Zombie
  {
  private String zAge;
  private String zType;
  private String zName;
  
  public Zombie(String zA, String zT, String zN)
  {
      zAge = zA;
      zType = zT;
      zName = zN;
  }
  
  public void setZAge(String zA)
  {
      zAge = zA;
  }
  
  public void setZType(String zT)
  {
      zType = zT;
  }
  
  public void setZName(String zN)
  {
      zName = zN;
  }
  
  public String getZAge()
  {
      return zAge;
  }
  
  public String getZType()
  {
      return zType;
  }
  
  public String getZName()
  {
      return zName;
  }
  
  public boolean equals(Zombie zomb)
  {
      if(zomb.getZAge() == zAge &amp;&amp; zomb.getZType() == zType &amp;&amp; zomb.getZName() == zName)
          return true;
      else
          return false;
  }
  }
  </code></pre>
  
  <p>LinkedBag.java</p>
  
  <pre><code>public class LinkedBag&lt;E&gt;
  {
  //Head node and number of nodes in bag
  private Node&lt;E&gt; head;
  private int manyNodes;
  
  //Constructor
  public LinkedBag()
  {
      head = null;
      manyNodes = 0;
  }
  
  //Returns the number of nodes in the bag
  public int getSize()
  {
      return manyNodes;
  }
  
  //Returns the node that is at the head of the linked list
  public Node&lt;E&gt; getListStart()
  {
      return head;
  }
  
  //Adds a node to the beginning of the list
  public void add(E element)
  {
      head = new Node&lt;E&gt;(element,head);       //Creates a new node pointing to the head and sets the head of the linked bag to the new Node
      manyNodes++;        //Increments Node counter
  }
  
  //Counts the number of times Node [target] occurs within the bag
  public int countOccurences(E target)
  {
      int count = 0;      //Initializes incrementable counter
  
      if(head==null)      //Checks if bag is empty and returns null if bag is empty
          return 0;
  
      if(head.getData().equals(target))       //Checks if the head of the linked list is [target]
          count++;            //Increments counter
  
      Node&lt;E&gt; cursor = head;      //Sets temporary Node [cursor] to the same value and pointer as head
  
      while(cursor.getLink() != null)     //Loops until the next Node contains no value
      {
          if(cursor.getLink().getData().equals(target))           //Checks if the value of the next Node is [target]
              count++;                //Increments counter
  
          cursor=cursor.getLink();            //Cursor continues down linked list
      }
  
      return count;       //Returns incremented int [count], number of occurences of [target]
  }
  
  //Checks if Node [target] exists within the bag
  public boolean exists(E target)
  {
      if(head.getData().equals(target))       //Checks if the head of the linked list is [target]
          return true;
  
      Node&lt;E&gt; cursor = head;      //Sets temporary Node [cursor] to the same value and pointer as head
  
      while(cursor.getLink() != null)     //Loops until the next Node contains no value
      {
              if(cursor.getData().equals(target))     //Checks if current Node is [target] and returns true if true
                  return true;
  
              cursor=cursor.getLink();        //Cursor continues down linked list
      }
              return false;       //Returns false if cursor goes through entire linked list and [target] isn't found
  }
  
  //Checks if Node [target] exists within the bag and removes the first occurence of it
  public boolean remove(E target)
  {       
      if(head==null)          //Returns false if bag is empty
          return false;
  
      if(head.getData().equals(target))   //If the head Node's data is [target]
      {
          head = head.getLink();      //Make the next Node the head
          manyNodes--;            //Decrements Node counter
          return true;            //Returns true, found [target]
      }
  
      Node&lt;E&gt; cursor = head;          //Sets temporary Node [cursor] to the same value and pointer as head
  
      while(cursor.getLink() != null)     //Loops until the next Node contains no value
      {
          cursor = cursor.getLink();      //Cursor continues down linked list
  
          if(cursor.getLink().getData().equals(target))   //If the next node's data is [target]
          {
              cursor.setLink(cursor.getLink().getLink());     //Sets current Node's link to the next Node's link, by passing the next Node
              manyNodes--;            //Decrements Node counter
              return true;            //Returns true, found [target]
          }
      }
      return false;           //Returns false, [target] not found
  }
  }
  </code></pre>
  
  <p>Node.java</p>
  
  <pre><code>public class Node&lt;E&gt;
  {
  private E data;
  private Node&lt;E&gt; link;
  
  
  public Node(E initialData, Node&lt;E&gt; initialLink)
  {
      data = initialData;
      link = initialLink;
  }
  
  public E getData()
  {
      return data;
  }
  
  public Node&lt;E&gt; getLink ()
  {
      return link;
  }
  
  public void setData(E element)
  {
      data = element;
  }
  
  public void setLink(Node&lt;E&gt; newLink)
  {
      link = newLink;
  }
  }
  </code></pre>
  
  <p>And this is the menu file that the user interacts with
  ZombiesProj2.java</p>
  
  <pre><code>import java.util.Scanner;
  
  public class ZombiesProj2
  {
  public static void main(String[] args) throws InterruptedException
  {
      LinkedBag&lt;Zombie&gt; zBag = new LinkedBag&lt;Zombie&gt;();       //Linked bag to hold Zombie Objects
      String choice = "";
  
      Scanner input = new Scanner(System.in);
  
      while(!choice.equalsIgnoreCase("x"))
      {   
          //Menu
          System.out.println("\nSac de Zombi\n");
          System.out.println("S - Display size of bag");
          System.out.println("A - Add 'Zombie' to bag");
          System.out.println("R - Remove 'Zombie' from bag");
          System.out.println("F - Find 'Zombie' in bag");
          System.out.println("D - Display contents of bag");
          System.out.println("X - Exit");
          System.out.print("Enter Selection: ");
  
          //Input and Output
          choice = input.nextLine();
  
          if(choice.equalsIgnoreCase("s"))
          {
              System.out.println("\nSize = " + zBag.getSize() + "\n");
          }
          else if(choice.equalsIgnoreCase("a"))       //adds zombie
          {
              String zAge;
              String zType;
              String zName;
  
              System.out.print("How many years has this zombie ROAMED THE EARTH: ");
              zAge = input.nextLine();
              System.out.print("What type of zombie is it: ");
              zType = input.nextLine();
              System.out.print("What would you like to name this zombie: ");
              zName = input.nextLine();
  
              Zombie newZomb = new Zombie(zAge,zType,zName);
              zBag.add(newZomb);
          }
          else if(choice.equalsIgnoreCase("r"))       //removes zombie
          {
              String zAge;
              String zType;
              String zName;
  
              System.out.print("How many years has this zombie ROAMED THE EARTH: ");
              zAge = input.nextLine();
              System.out.print("What type of zombie is it: ");
              zType = input.nextLine();
              System.out.print("What is the name of the zombie: ");
              zName = input.nextLine();
  
              Zombie rZomb = new Zombie(zAge,zType,zName);
  
              zBag.remove(rZomb);
          }
          else if(choice.equalsIgnoreCase("f"))       //counts number of matching zombies
          {
              String zAge;
              String zType;
              String zName;
  
              System.out.print("How many years has this zombie ROAMED THE EARTH: ");
              zAge = input.nextLine();
              System.out.print("What type of zombie is it: ");
  
              zType = input.nextLine();
              System.out.print("What is the name of the zombie: ");
              zName = input.nextLine();
  
              Zombie fZomb = new Zombie(zAge,zType,zName);
  
              System.out.println("The " + zAge + " year old zombie type " + zType + " named " + zName + " occurs " + zBag.countOccurences(fZomb)+ " time(s)");
          }
          else if(choice.equalsIgnoreCase("d"))       //displays entire zombie 'bag'
          {
              Node cursor = zBag.getListStart();
              Zombie dZomb;
              while(cursor !=null)
              {
                  dZomb = (Zombie)cursor.getData();
                  System.out.print("[Zombie "+dZomb.getZAge()+" "+dZomb.getZType()+" "+dZomb.getZName()+"],");
                  cursor = cursor.getLink();
              }
          }
          else if(!choice.equalsIgnoreCase("x"))  
          {
              System.out.println("Error: Invalid Entry");
          }
      }
  }
  }
  </code></pre>
  
  <p>Updated equals and hashCode</p>
  
  <pre><code>public boolean equals(Object obj)
  {
      if(obj==null)
          return false;
      if(obj==this)
          return true;
      if(obj.getClass() != getClass())
          return false;
  
      Zombie zomb = (Zombie)obj;
      if(zomb.getZAge().equals(zAge) &amp;&amp; zomb.getZType().equals(zType) &amp;&amp; zomb.getZName().equals(zName))
          return true;
      else
          return false;
  }
  
  public int hashCode() { return 0; }
  </code></pre>