So like the title says I'm trying to input a node in the third position of the linked list. The way I originally tried to do it was to insert two places down the list after numberOfItems was >= 3. I figured if I was getting an error it would be outputting the last 2 Players wrongly but it's just continuing to output Player 1. Can anybody point me to the right direction as to why this is happening?
Here is my linkedlist class
public class PlayerLinkedList extends ShellLinkedList
{
public PlayerLinkedList()
{
super();
}//end PlayerLinkedList constructor
public void insert(Player p)
{
if(numberOfItems >= 3)
{
PlayerNode pn = new PlayerNode(p);
head = pn;
pn.setNext(head.getNext().getNext());
numberOfItems++;
}
else
{
PlayerNode pn = new PlayerNode(p);
if(head == null)
{
head = pn;
}
pn.setNext(head);
head = pn;
numberOfItems++;
}
}//end insert method
public Player delete(int searchID) throws DataStructureException
{
PlayerNode current = head;
PlayerNode previous = null;
while(current != null && current.getPlayer().getID()!=searchID)
{
previous = current;
current = current.getNext();
}//end while
if(current == null) //not found
throw new DataStructureException(searchID + "not found: cannot be deleted");
else
{
if(current == head)
head = head.getNext(); //delete head
else
previous.setNext(current.getNext());
numberOfItems--;
return current.getPlayer();
}//end else
}//end delete
}//end class
Also just for reference here is my ShellLinkedList class
public abstract class ShellLinkedList
{
protected PlayerNode head;
protected int numberOfItems;
public ShellLinkedList()
{
head = null;
numberOfItems = 0;
}//end ShellLinkedList constructor
public int getNumberOfItems()
{
return numberOfItems;
}// end of getnumberOfItems
public boolean isEmpty()
{
return (numberOfItems==0);
}//end isEmpty
public String toString()
{
String listString="";
PlayerNode current = head;
for(int i = 0; i<numberOfItems && current != null; i++)
{
listString += current.getPlayer().toString()+"\n";
current = current.getNext();
}
return listString;
}//end toString
}//end class
My input is:
Player one = new Player(1, "Mike", "Mario");
Player two = new Player(2, "Brian", "Halo");
Player three = new Player(3, "John", "Minecraft");
Player four = new Player(4, "Thrall", "WoW");
Player five = new Player(5, "Scott", "Metroid");
list.insert(one);
list.insert(two);
list.insert(three);
list.insert(four);
list.insert(five);
System.out.println(list.toString());
And my output is:
id: 3 name: John game: Minecraft
id: 2 name: Brian game: Halo
id: 1 name: Mike game: Mario
id: 1 name: Mike game: Mario
id: 1 name: Mike game: Mario
There are a few problems with your code, your insert method behaves differently when numberOfItems >= 3 which is why you are not able to add more than 3 times. In that code block you are creating a new PlayerNode instance but you do not keep any reference to it.
You should also check whether you are expecting normal List#add behaviour which appends to the end of a list not the beginning.
I solved the issue by adding
head.getNext().setNext(pn);
after
pn.setNext(head.getNext().getNext());
Related
(disclaimer: for school, so cant import other Java utilities)
So I have to merge sort on a linked list, and I have almost all of it down. Here it is:
class musicNode {
String track; // The name of the track
int played= 0; // The number of times played
int shuffleTag= 0; // For shuffling
musicNode next;
public musicNode() { // Here's how we construct an empty list.
next = null;
}
public musicNode(String t) {
track = t; next = null;
}
public musicNode(String t, musicNode ptr) {
track = t; next = ptr;
}
public boolean LTTrack(musicNode x) { // Compares tracks according to alphabetical order on strings
if (this.track.compareTo(x.track)<=0) return true;
else return false;
}
};
// This class represents a playlist;
// We assume that each track appears at most once in the playlist
public class MusicPlayer {
protected musicNode head = null; // Pointer to the top of the list.
int length=0; // the number of nodes in the list.
boolean debug= false;
public MusicPlayer() {
}
public void setToNull() {
head = null;
}
public boolean isEmpty() {
return head == null;
}
public musicNode head() {
return head;
}
void insertTrack(String name) { // Inserts a new track at the top of the list.
musicNode temp= new musicNode(name, head);
head= temp;
length++;
}
void sortTrack() { // TODO
musicNode main = this.head;
mergeSort(main);
}
public musicNode mergeSort(musicNode head) {
if ((head == null) || (head.next == null)){
return head;
}
musicNode left = head;
musicNode right = head.next;
while((right != null) && (right.next != null)){
head = head.next;
right = (right.next).next;
}
right = head.next;
head.next = null;
return merge(mergeSort(left), mergeSort(right));
}
There also this JUnit test:
public void testSortMixed() {
MusicPlayer trackList= new MusicPlayer();
trackList.insertTrack("d");
trackList.insertTrack("b");
trackList.insertTrack("e");
trackList.insertTrack("a");
trackList.insertTrack("c");
MusicPlayer trackListTwo= new MusicPlayer();
trackListTwo.insertTrack("e");
trackListTwo.insertTrack("d");
trackListTwo.insertTrack("c");
trackListTwo.insertTrack("b");
trackListTwo.insertTrack("a");
trackList.sortTrack();
musicNode tmp= trackList.head;
musicNode tmp2= trackListTwo.head;
for(int i=0; i< 5; i++){
assertEquals(tmp2.track, tmp.track);
tmp2= tmp2.next;
tmp=tmp.next;
}
}
The problem is that it sorts according to the last track you insert, and only from then on. So say you insert alphabets from a-f, but the last one you insert was "c", itll only show you "cdef". But if the last one was "a" then it works as intended.
So how it works is, when you insert a track it gets inserted onto the beginning of the list, not end, becoming the head. I feel like that may be whats messing it up, as I adapted and looked from my notes and online which insert at the bottom.
I dont know how to account for this though. Also I know it sorts based on what was inserted last (in the JUnit test above it sorts to "cde" because I created a main function and played around with it)
ANY help appreciated.
The key point is the second line in the method sortTrack:
void sortTrack() {
musicNode main = this.head;
this.head = mergeSort(main); // you forgot to set the head of linked list to the merged
}
I'd tested it in my laptop and everything goes okay now xD
I'm having a couple issues with the Josephus game. My first issue is that I can't figure out how to start counting at the person to the left of the person eliminated each round (game goes clockwise). It deletes correctly, but starts counting at the person to the right of the deleted person. My second issue is that I can't figure out how to print the eliminated person each round. I have the algorithm down for the most part, but I can't figure out these small details. Any help would be appreciated!
import java.io.*;
////////////////////////////////////////////////////////////////
class Link
{
public int iData; // data item (key)
public Link next; // next link in list
// -------------------------------------------------------------
public Link(int id) // constructor
{ iData = id; }
// -------------------------------------------------------------
public void display() // display ourself
{ System.out.print(iData + " "); }
} // end class Link
////////////////////////////////////////////////////////////////
class CircList
{
private Link current; // ref to current link
private int count; // # of links on list
// -------------------------------------------------------------
public CircList() // constructor
{
count = 0; // no links on list yet
current = null;
}
// -------------------------------------------------------------
public boolean isEmpty()
{ return count==0; }
// -------------------------------------------------------------
public int getSize()
{ return count; }
// -------------------------------------------------------------
public void insert(int id) // insert after current link
{ // make new link
Link newLink = new Link(id);
if(count == 0) // if first one
{
current = newLink; // current points to it
current.next = current; // next one is us
}
else
{
newLink.next = current.next; // downstream of new link
current.next = newLink; // upstream of new link
}
count++; // one more link
}
// -------------------------------------------------------------
public Link delete() // delete link following currrent
{
Link tempLink;
switch(count)
{
case 0: // current is already null
tempLink = current;
break;
case 1: // delete ourself
tempLink = current;
current = null;
count--;
break;
default: // delete the next one
tempLink = current.next;
current.next = tempLink.next;
count--;
break;
}
return tempLink;
}
// -------------------------------------------------------------
public Link find(int key) // find link with given key
{ // at one past current
int getHome = count;
while(getHome > 0) // while not back to
{ // beginning
if(current.next.iData == key) // found it?
return current.next; // return next one
else // not found
{ // go to next link
current = current.next;
getHome--; // one item closer to home
}
}
return null; // can't find it
}
// -------------------------------------------------------------
public Link delete(int key) // delete link with given key
{
Link nextLink = find(key); // find it
if(nextLink != null) // if found,
{
current.next = nextLink.next; // delete it
count--;
}
return nextLink; // return null or link
}
// -------------------------------------------------------------
public void display() // display the list
{
for(int j=0; j<count; j++)
{
current.next.display();
current = current.next;
}
System.out.println("");
}
// -------------------------------------------------------------
public void step()
{
if(count != 0)
current = current.next; // go to next link
}
// -------------------------------------------------------------
public Link peek()
{ return current.next; }
// -------------------------------------------------------------
} // end class CurcList
////////////////////////////////////////////////////////////////
class CircApp
{
public static void main(String[] args) throws IOException
{
int j, nPlayers, nSkips, startNo;
CircList theList = new CircList(); // make list
putText("Enter the number of players: ");
nPlayers = getInt();
for(j=nPlayers; j>0; j--) // number 10, 20, ...
theList.insert(j);
putText("Players: ");
theList.display();
putText("Enter the the number of spaces to skip: ");
nSkips = getInt();
putText("Enter the the starting player's number: ");
startNo = getInt();
// Add your code here
int m = 1, n;
while(m != startNo)
{
theList.step();
m++;
}
putText("Players: ");
theList.display();
while(theList.getSize() > 1){
n = 0;
while(n != nSkips){
theList.step();
n++;
}
theList.delete();
theList.display();
}
}
// end main()
// -------------------------------------------------------------
public static void putText(String s)
{
System.out.print(s);
System.out.flush();
}
// -------------------------------------------------------------
public static String getString() throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
// -------------------------------------------------------------
public static char getChar() throws IOException
{
String s = getString();
return s.charAt(0);
}
//-------------------------------------------------------------
public static int getInt() throws IOException
{
String s = getString();
return Integer.parseInt(s);
}
// -------------------------------------------------------------
} // end class CircApp
Displaying the deleted player is a very easy to fix. Your delete() method returns the deleted Link, so you just need to use it when it's returned. Instead of just calling theList.delete() use something like:
theList.delete().display(); //start line
System.out.println("is eliminated"); //finish line
As for starting to the left of the deleted player, you need a way to move backwards through your circle. In small circles one way to do this is to step() one time fewer than the number of players (since stepping one time for each player makes a full trip around the circle back to the current player). So after the above code add
for(int i=0; i<theList.getSize()-1; i++)
theList.step();
I hope I understand you correctly - you want to start counting on the next person from the deleted, not the one before. Something like that:
public Link delete(int key) // delete link with given key
{
Link nextLink = find(key); // find it
if(nextLink != null) // if found,
{
current.next = nextLink.next; // delete it
current = current.next; //move to the next person
count--;
}
return nextLink; // return null or link
}
As for the second question - you return the deleted element, just print it like so:
Link retVal = theList.delete();
if (retVal != null) {
retVal.display();
}
I have made a custom linked list and node classes for school and I have decided to practice how to use it by making a text-twist like game
In my linked list class, I have a traverse method which prints out the word and how long the word is into the console.
The code I have so far is this:
MyLinkedList.java
package game;
public class MyLinkedList {
public int counter;
public MyNode head;
public MyNode tail;
public MyLinkedList() {
counter = 0;
}
public void InsertToHead(MyNode m) {
if (counter == 0) {
head = tail = m;
} else {
m.setNext(head);
head.setPrev(m);
head = m;
}
counter++;
}
public int size() {
return counter;
}
public boolean isEmpty() {
if (counter == 0) {
return true;
} else {
return false;
}
}
public MyNode retrieveWord(String s) {
MyNode n = head;
while (n.next != null) {
if (s.equals(n.getWord())) {
return n;
} else {
n = n.next;
}
}
if (s.equals(tail.getWord())) {
return tail;
}
return null;
}
public MyNode retrieveLength(int l) {
MyNode n = head;
while (n.next != null) {
if (l == n.getLength()) {
return n;
} else {
n = n.next;
}
}
if (l == tail.getLength()) {
return tail;
}
return null;
}
public void traverse() {
MyNode n = head;
if (head != null) {
while (n.next != null) {
System.out.println(n.getWord() + "\t" + n.getLength());
n = n.next;
}
System.out.println(tail.getWord() + "\t" + n.getLength());
}
}
}
MyNode.java
package game;
public class MyNode {
public String word;
public int length;
public MyNode next, previous;
public MyNode() {
word = null;
length = 0;
next = null;
previous = null;
}
public MyNode(String w, int l) {
word = w;
length = l;
next = null;
previous = null;
}
public void setNext(MyNode n) {
next = n;
}
public void setPrev(MyNode n) {
previous = n;
}
public void toHead(MyNode n){
while(n.previous != null){
n.setPrev(n);
}
}
public void setWord(String w){
word = w;
}
public String getWord(){
return word;
}
public void setLength(int l){
length = l;
}
public int getLength(){
return length;
}
public boolean hasNext(){
return next != null;
}
}
WordSort.java
package game;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class WordSort {
Scanner wordScan;
public WordSort() {
MyLinkedList sixLetters = new MyLinkedList();
MyLinkedList fiveLetters = new MyLinkedList();
MyLinkedList fourLetters = new MyLinkedList();
MyLinkedList threeLetters = new MyLinkedList();
MyLinkedList rejects = new MyLinkedList();
try {
wordScan = new Scanner(new File("corncob_lowercase.txt"));
wordScan.useDelimiter("\r\n");
MyLinkedList ll = new MyLinkedList();
while (wordScan.hasNext()) {
String temp = wordScan.next();
MyNode node = new MyNode();
node.setWord(temp);
node.setLength(temp.length());
ll.InsertToHead(node);
if (temp.length() == 6) {
sixLetters.InsertToHead(node);
} else if (temp.length() == 5) {
fiveLetters.InsertToHead(node);
} else if (temp.length() == 4) {
fourLetters.InsertToHead(node);
} else if (temp.length() == 3) {
threeLetters.InsertToHead(node);
} else {
rejects.InsertToHead(node);
}
}
wordScan.close();
threeLetters.traverse();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("Missing File: corncob_lowercase.txt");
}
}
}
and finally, Driver.java
package game;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Driver extends JPanel {
private static final long serialVersionUID = 1L;
public Driver() {
new WordSort();
}
public static void main(String[] args) {
JFrame frame = new JFrame("Hidden Word");
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new Driver());
frame.setVisible(true);
}
}
Whenever I run this code, all the linked lists (threeLetters, fourLetters, fiveLetters, and sixLetters) are completely fine until the very end, when threeLetters.traverse() is called, I get this output (only the end portion)
act 3
ace 3
aby 3
abe 3
abducts 7
abductors 9
abductor 8
abductions 10
abduction 9
abducting 9
abducted 8
abdominal 9
abdomens 8
abdomen 7
abdication 10
abdicating 10
abdicates 9
abdicated 9
abdicate 8
abbreviations 13
abbreviation 12
abbreviating 12
abbreviates 11
abbreviated 11
abbreviate 10
abattoirs 9
abattoir 8
abatement 9
abashed 7
abasement 9
abandons 8
abandonment 11
abandoned 9
abandon 7
abalone 7
aardwolf 8
abe 8
I can't seem to find out why it's occurring, but it looks like it's printing out everything after abe and it prints abe twice, once with it registering as 3 letters and once as 8 letters long!
I got the text file from this website:
http://www.mieliestronk.com/corncob_lowercase.txt
Your problem here is mainly one of design. The main flaw: attempting to use one instance MyNode in multiple linked lists.
When you InsertToHead(node) you're modifying the contents of node itself, specifically the head and next references.
Fix:
Simple declare a new MyNode for each LinkedList you want to use it in. In your project specifically you're using two for any given node. ll and one of the <inset_number>Letters lists. So declare a new MyNode for each list:
...
while (wordScan.hasNext()) {
String temp = wordScan.next();
MyNode node = new MyNode();
MyNode node2 = new MyNode();
node.setWord(temp);
node2.setWord(temp);
node.setLength(temp.length());
node2.setLength(temp.length());
ll.InsertToHead(node2);
...
That should fix your problem.
If you want to know WHY it was happening. Trace the code. It has to do with attempting to add nodes that already have some more nodes attached into a list.
Additional Notes:
Try your best to avoid public fields unless you're SURE you want them. I.E. in MyLinkedList someone using your class shouldn't be able to access (or even see!) the counter, head or tail, so those should be made private. If you really want to access them, create get and set methods
Your nested if block in WordSort is a perfect place for a switch like this:
switch(temp.length()) {
case 6:
sixLetters.InsertToHead(node);
break;
case 5:
fiveLetters.InsertToHead(node);
break;
case 4:
fourLetters.InsertToHead(node);
break;
case 3:
threeLetters.InsertToHead(node);
break;
default:
rejects.InsertToHead(node);
break;
}
MyNode works fine as a separate class. However I will many times choose to implement a simple class like a node as a nested class. It can make for some very clean code. Try it out!
Be careful when designing your classes. There are a lot of extra methods in your design. It can be easy to chug ahead creating methods you may or may not ever use. I like to only create methods when I see that I need them in a class that uses the class in question.
Happy Coding!
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; }
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.
Your equals method should have the same signature as that in Object Zombie.equals(Object). And, the first thing it should do is return false if the argument is not a Zombie.
Whenever you write an equals method, you must also write a hashCode method. Look at most any example for details.
Never use the equals operator for Strings. Always use the equals method. Replace zomb.getZAge() == zAge with zomb.getZAge().equals(zAge).
Why is zAge a String? You can let it be some sort of number.
There's no need to put 'Z' everywhere in your class. It's in a 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.
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;
}
After calling the remove method, I call display and I'm getting an empty list; however, if I call the display method first it will display the correct list, I'm guessing the "first" value reached the end of the list or I got a broken node somewhere. Any help appreciated
public class LinkedList {
private Node first;
public LinkedList()
{
first = null;
}
//add students to the list
public void add(Student s)
{
Node newNode = new Node(s);
newNode.next = first;
first = newNode;
}
//remove duplicate records (return true if duplicate found)
public boolean remove(String fn, String ln)
{
Student remove;
boolean found = false;
int duplicate = 0;
while(first != null)
{
if(first.value.getFname().equals(fn) && first.value.getLname().equals(ln))
{
duplicate++;
if(duplicate > 1)
{
remove = first.value;
found = true;
}
}
first = first.next;
}
if(found)
return found;
else
return found;
}
//display list of student
public void display()
{
if(first == null)
System.out.println("List is empty!");
else
{
while(first != null)
{
System.out.println(first.value);
first = first.next;
}
}
}
}
main
public class Tester {
public static void main(String[] args) {
UnderGrad john = new UnderGrad("john", "doe", 2.7, "computer Science", "phisics");
UnderGrad jorge = new UnderGrad("jorge", "vazquez", 3.8, "computer Science", "programming");
UnderGrad john2 = new UnderGrad("john", "doe", 3.0, "Computer Engineering", "phisics");
Advisor jim = new Advisor("jim", "smith");
Grad jane = new Grad("jane", "doe", 3.0, "Electric Engineering", jim);
LinkedList students = new LinkedList();
students.add(john);
students.add(jorge);
students.add(john2);
students.add(jane);
System.out.println(students.remove("john", "doe"));
students.display();
}
}
output
run:
true
List is empty!
BUILD SUCCESSFUL (total time: 1 second)
You're using the linked list's head (first) as an iterator in the remove method. Instead, use a local variable:
for (Node current = first; current != null; current = current.next) {
if (current.value.getFname().equals(...
...
...
}
You have a few bugs. You cannot possibly mean this:
if(found)
return found;
else
return found;
That will always return true.
Set a breakpoint, draw a picture of the data structure (yes with a pencil) and watch the data structure in the debugger as you walk through the code.
If you get a code answer here, you will not be able to figure out the next assignment either. Sorry.
-Professor Archibald.
Step through your code and pay attention to what happens to the value of first after the first call to remove(...).
Hint: it will be null.
Since LinkedList.first is the only reference from LinkedList to its contents, after you call remove() the list has 'forgotten' what it contains.
the problem is in your add( ) method. look in there. :)