Reputation: 2781
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.
Zombie.java
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 && zomb.getZType() == zType && zomb.getZName() == zName)
return true;
else
return false;
}
}
LinkedBag.java
public class LinkedBag<E>
{
//Head node and number of nodes in bag
private Node<E> 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<E> getListStart()
{
return head;
}
//Adds a node to the beginning of the list
public void add(E element)
{
head = new Node<E>(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<E> 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<E> 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<E> 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
}
}
Node.java
public class Node<E>
{
private E data;
private Node<E> link;
public Node(E initialData, Node<E> initialLink)
{
data = initialData;
link = initialLink;
}
public E getData()
{
return data;
}
public Node<E> getLink ()
{
return link;
}
public void setData(E element)
{
data = element;
}
public void setLink(Node<E> newLink)
{
link = newLink;
}
}
And this is the menu file that the user interacts with ZombiesProj2.java
import java.util.Scanner;
public class ZombiesProj2
{
public static void main(String[] args) throws InterruptedException
{
LinkedBag<Zombie> zBag = new LinkedBag<Zombie>(); //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");
}
}
}
}
Updated equals and hashCode
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) && zomb.getZType().equals(zType) && zomb.getZName().equals(zName))
return true;
else
return false;
}
public int hashCode() { return 0; }
Upvotes: 3
Views: 30416
Reputation: 7889
I know that because you are trying to learn programming you are writing your own linked list
instead of using Java's LinkedList
. However, there are a few things you have missed.
Object
Zombie.equals(Object)
. And, the first thing it should do is return false
if the argument is not a Zombie.zomb.getZAge() == zAge
with zomb.getZAge().equals(zAge)
.String
? You can let it be some sort of number.Zombie
; your readers know. At work, I have colleagues who insist on repeating class names in all their variables.This is not good code.
public class Document {
private Long documentId;
private String documentName;
private String documentAuthor;
private Date documentPublicationDate;
// 10 more instance variables.
// Constructors, accessors, other code.
}
And then they name variables of type Document
as documentA
, documentB
, etc. How boring, repetitious, and redundant.
Upvotes: 3
Reputation: 48599
1) Why would you name a variable that contains the node count 'manyNodes' instead of 'nodeCount'. If you asked some random programmer what a variable named 'manyNodes' contained, do you think they would be able to guess? What if you asked some random programmer what the variable nodeCount contained? Do you think the random programmer could even guess the type of nodeCount? What about the type of 'manyNodes'?
2) How about trying something like this:
public void add(Node<E> element)
{
if (head == null) {
head = element;
}
else {
tail.nextNode = element;
}
tail = element;
nodeCount++; //Increments Node counter
}
public class Node<E>
{
private E data;
private Node<E> nextNode;
}
public class LinkedBag<E>
{
private Node<E> head;
private Node<E> tail;
private int nodeCount;
}
//Constructor
public LinkedBag()
{
head = tail = null;
nodeCount = 0;
}
Upvotes: 0