This is just a test program (my original program gets data from a file so i omitted that since it might complicate people from understanding my problem)
Anyways, I tried deep copying my object data but I'm get a "null" when i print the copy method? what's wrong with the code? is this how we deep copy using recursion? if not, any tips to deep copying? Any other ways to keep copy apart from recursion? I'm not entirely sure if what I'm doing is right honestly since i'm reusing the copy method from a source.
Main
public static void main(String[] args) {
Person person = new Person();
person.setFirstName("James");
person.setLastName("Ryan");
person.setAge(19);
Person personTwo = new Person();
personTwo.setFirstName("Steve");
personTwo.setLastName("rivera");
personTwo.setAge(22);
LinkedList lList = new LinkedList();
// add elements to LinkedList
lList.add(person);
lList.add(personTwo);
//node
Node str;
"Variable str might not have been initialized"
//deep copy
Node copy = Node.copy(str);
System.out.println(copy);
}
LinkedList
class LinkedList {
// reference to the head node.
private Node head;
private int listCount;
// LinkedList constructor
public LinkedList() {
// this is an empty list, so the reference to the head node
// is set to a new node with no data
head = new Node(null);
listCount = 0;
}
public void add(Object data) // appends the specified element to the end of this list.
{
Node Temp = new Node(data);
Node Current = head;
// starting at the head node, crawl to the end of the list
while (Current.getNext() != null) {
Current = Current.getNext();
}
// the last node's "next" reference set to our new node
Current.setNext(Temp);
listCount++;// increment the number of elements variable
}
public int size() // returns the number of elements in this list.
{
return listCount;
}
public String toString() {
Node Current = head.getNext();
String output = "";
while (Current != null) {
output += "[" + Current.getData().toString() + "]";
Current = Current.getNext();
}
return output;
}
}
Node
class Node {
// reference to the next node in the chain,
// or null if there isn't one.
Node next;
// data carried by this node.
// could be of any type you need.
Object data;
// Node constructor
public Node(Object dataValue) {
next = null;
data = dataValue;
}
// another Node constructor if we want to
// specify the node to point to.
public Node(Object dataValue, Node nextValue) {
next = nextValue;
data = dataValue;
}
// these methods should be self-explanatory
public Object getData() {
return data;
}
public void setData(Object dataValue) {
data = dataValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
Here is the copy method within the Node class
public static Node copy(Node str) {
if (str == null) {
return null;
}
Node copyFirst = new Node(str.data, null);
copyFirst.next = copy(str.next);
return copyFirst;
}
}
Person
class Person {
private String firstName;
private String lastName;
private int age;
public Person() {
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//Overriding toString to be able to print out the object in a readable way
//when it is later read from the file.
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append(firstName);
buffer.append(" ");
buffer.append(lastName);
buffer.append(" ");
buffer.append(age);
buffer.append(" ");
return buffer.toString();
}
Thanks
//dummy variable
Node str = null;
//deep copy
Node copy = Node.copy(str);
System.out.println(copy);
What did you expect?
You need to copy the list, not some dummy node. For that, LinkedList needs to support copying (or at least a way to iterate over its elements). Node should be an implementation detail completely hidden from the users of LinkedList.
A shallow copy is when you reuse the node values as is. eg. you loop through your Nodes making new Node with the same values and chaining the new nodes together. You'll need to keep the first as the reference for the new LinkedList object.
A deep copy is when the data is also cloned. If all your objects implements Cloneable you just implement clone as describes above and instead of making new node with the same value you just make a clone of the value for the new Node and voilĂ , you got a deep copy.
Related
hello how can I make a method that add an element at the beginning of my list.
I know that I have to create a new Pokeball here, point new pokeball.next as the head and point the head to the new Pokeball but I don't know how to do it
My list looks like this right now :
Bulbasaur -> Squirtle
I want to add charmander at the beginning
Charmander -> Bulbasaur -> Squirtle
When calling the method : d1.prepend(p3), It has to go through Trainer class then Pokeball class just like my addPokemon method thank you
public class test {
public static void main(String[] args) {
Pokemon p1 = new Pokemon("Bulbasaur", "grass");
Pokemon p2 = new Pokemon("Squirtle", "water");
Pokemon p3 = new Pokemon("Charmander", "fire");
Trainer d1 = new Trainer("Pierre");
d1.addPokemon(p1);
d1.addPokemon(p2);
}
}
public class Pokemon {
private String name;
private String type;
private int niveau;
public Pokemon(String name, String type) {
this.name = name;
this.type = type;
this.niveau = (int) (Math.random() * (1 * 1 - 100) + 100);
}
}
public class Trainer {
public final String name;
private Pokeball head;
public Trainer(String name) {
this.name = name;
}
public void addPokemon(Pokemon pok) {
if (this.head != null) {
this.head.addPokemon(pok);
} else {
this.head = new Pokeball(pok);
}
}
public void prepend(Pokemon pok) {
this.head.prepend(pok);
}
}
public class Pokeball {
private Pokemon pok;
private Pokeball next;
public Pokeball(Pokemon pok) {
this.pok = pok;
}
public Pokeball(Pokemon pok, Pokeball next) {
this.pok = pok;
this.next = next;
}
public void addPokemon(Pokemon pok) {
Pokeball current = this;
while (current.next != null) {
current = current.next;
}
current.next = new Pokeball(pok);
}
public void prepend(Pokemon pok) {
}
}
You cannot call prepend on a Pokeball to attach something behind it unless each Pokeball also holds a reference to the previous Pokeball.
The solution is actually much simpler than that. Just make your new Pokeball the head of your list:
public class Trainer {
public final String name;
private Pokeball head;
...
public void prepend(Pokemon pok) {
Pokeball newPokeball = new Pokeball(pok);
newPokeball.next = this.head;
this.head = newPokeball;
}
}
EDIT:
Another fun exercise is to try to add a pokeball in the middle of a list:
Bulbasaur -> Charmander -> Squirtle
To do this you just need to start from head and go until you find the pokeball that you want to add your new one after. The rest is very similar to above.
public void addAfterPokeball(Pokemon theOneToInsertAfter, Pokemon pok) {
Pokeball newPokeball = new Pokeball(pok);
Pokeball tmp = head;
while (tmp != null && tmp.pok.name != theOneToInsertAfter.name) {
tmp = tmp.next;
}
if (tmp!=null){
newPokeball.next = tmp.next;
tmp.next = newPokeball;
} else {
//could not find the pokeball to insert after
}
}
There's Collections classes that will help you here. If you create a LinkedList of Pokemon, this supports addFirst() to insert at the head of the list.
List<Pokemon> list = new LinkedList<>();
//other pokemon inserted here
// ...
//insert new item at front of list
list.addFirst(newPokemon);
I try to guess what you want to do. I think you try to implement a chained list of your own.
You need to instantiate a Pokeball and add the current first element of your list as the next element of the instance you just created. I guess your List object contains a reference to your first element, it needs to be changed as well.
This is a very specific question, and I can't seem to find anything in particular which helps. I have a singly linked list( not an implemented linked list, which is all I've been able to find)in which the nodes store a Student object.Each Student object has variables, although I'm having trouble accessing each variable.
I think it's supposed to be similar to how you'd iterate through an array of objects.But that uses the for loop.And to traverse a linked list you have to work with the nodes and their next&data values.
I'm not entirely sure how to go about combining the 2 ideas.I feel like it's either something stupidly simple I'm not getting, or there's an entirely different approach I'm supposed to be taking.
import java.util.scanner;
public class StudentNode extends Student
{
private Student data;
private StudentNode next;
class SinglyLinkedList
{
private StudentNode first;
//constructor
public SinglyLinkedList()
{
first=null;
}
public addToList(Student newData)
{
StudentNode newNode= new StudentNode();
newNode.data=newData;
newNode.next=first; //refs to the element first is currently pointing to
first=newNode;//first now refs to added element
}
public courseMark(Student data)
{
double cm=courseMark(StudentNode.data);
return "Student number : "+stuNum +"Course Mark: "+cm;
}
public double classAverage(Student data)
{
//traverses linked list, not enirely sure about how to access the course mark
double classAvg=0;
double sum = 0;
int i=0;
StudentNode current = first;
StudentNode previous = null;
while (current != null)
{
i++;
StudentNode current= Student.courseMark();
sum += current.data;//not sure bout course mark access
previous = current;
current = current.next;
}
return classAvg=sum/i;
}
And here's the Student class which the data component uses. Not sure if it'll be needed to answer.
public class Student
{
private String name;
private String stuNum;
private int firstTest;
private int secondTest;
private int thirdTest;
public Student(String n,String sN,int fT,int sT,int tT)
{
name=n;
stuName=sN;
firstTest=fT;
secondTest=sT;
thirsTest=tT;
}
//setters
public void setName(String n)
{
name=n;
}
public void setStuNum(String sN)
{
stuNum=sN;
}
public void setFirstTest(int fT)
{
firstTest=fT;
}
public void setSecondTest(int sT)
{
secondTest=sT;
}
public void setThirdTest(int tT)
{
thirdTest=tT;
}
//getters
public String getName()
{
return name;
}
public String getStuNum()
{
return stuNum;
}
public int getFirstTest()
{
return firstTest;
}
public int getSecondTest()
{
return secondTest;
}
public int getThirdTest()
{
return thirdTest;
}
//course mark computer
public double courseMark()
{
double crseMark=(firstTest*0.25)+(secondTest*0.25)+(thirdTest*0.50);
return crseMark;
}
}
You must traverse from the node to the student data to get the courseMark.
while (current != null) {
...
double courseMark = current.data.courseMark();
...
}
My program is not sorting the list and I can't figure out the problem.
The list is the same before sorting and after sorting.
public void SelectionSort(){
for (Node index = head; ((index != null)&&(index.getnext()!=null)); index = index.getnext()) {
Node min = index;
for (Node test = min.getnext(); test != null; test = test.getnext()) {
if (test.getAcc().compareTo(min.getAcc()) < 0){
min = test;
}
}
if(index!=min){
Node temp = new Node();
temp=index;
index=min;
min =temp;
}
}
}
Below is my class Node:
public class Node {
private int ID;
private String Acc;
private String Symbol;
private String Function;
private String UniGene;
private String Chromosome;
private Node next;
public Node(){
}
public Node(int id, String acc,String unigene, String symbol, String chromosome, String function){
ID=id;
Acc=acc;
Symbol=symbol;
UniGene = unigene;
Chromosome = chromosome;
Function=function;
}
public void displayNode() // display
{
System.out.print("{"+ID+","+Acc+","+Symbol+","+Function+"} \n");
}
int getID(){
return ID;
}
String getAcc(){
return Acc;
}
String getUniGene(){
return UniGene;
}
String getSymbol(){
return Symbol;
}
String getChromosome(){
return Chromosome;
}
String getFunction(){
return Function;
}
void setnext(Node newnode)
{
next = newnode;
}
Node getnext()
{
return next;
}
}
I think that the problem is that you need to take care of the next pointer when you move nodes. In your original code you just swap 2 references, but you don't change the order in the list:
Node next = min.getnext();
min.setnext(index);
index.setnext(next);
This won't work directly, but the problem lies there. You'll need to save the "previous" node, and set previous.setnext(index) or something like that.
BTW:
Node temp = new Node();
temp=index;
You create a new Node, but you don't use it, 'cause in the next line you assign index to temp.
Node temp = index;
I have a linked list class that provides a Node class.
I need to implement a sort class to sort out the contents of the linked list class in alphabetical order.
I also need to implement a find method so that the find method will return all the data of the index it matches to.
list.addFirst(new Contact1("John Harvey" ,6000, "jh#gmail.com"));
list.addFirst(new Contact1("Cris Irish",2000, "cI#gmail.com"));
"John Harvey" and "Cris Irish" are the names. I want to compare Cris Irish John Harvey and arrange them in alphabetical order.
Then I want to use the find method so that find("Cris Irish") returns :
"Cris Irish",2000, "cI#gmail.com"
And I wanna use a comparator to do it. But I have no idea how to pass it as an argument in the method.
This is my comparator class
public class ContactComparator implements Comparator<Contact1>{
#Override
public int compare(Contact1 a, Contact1 b)
{
return b.getName().charAt(0)-(a.getName().charAt(0));
}
}
I have a contact1 class that defines the contents if the linked list.
import java.util.Collections;
import java.util.Comparator;
import java.util.NoSuchElementException;
package project3;
import java.util.Collections;
import java.util.Comparator;
import java.util.NoSuchElementException
public class LinkedList
{
private static Node first;
private int currentSize;
private static LinkedList list = new LinkedList();
/**
* Constructs an empty linked list
*/
public LinkedList()
{
first = null;
currentSize=0;
}
/**
* Returns the first element in the linked list.
* #return the first element in the linked list
*/
public Object getFirst()
{
return first;
}
/**
* Removes the first element in the linked list.
* #return the removed element
*/
public Object removeFirst()
{
if (first == null) { throw new NoSuchElementException(); }
Object element = first.data;
first = first.next;
currentSize--;
return element;
}
/**
* Adds an element to the front of the linked list.
* #param the element to add
*/
public void addFirst(Object element)
{
Node newNode = new Node();
newNode.data = element;
newNode.next = first;
first = newNode;
currentSize++;
}
/**
* A linked list node, holding the data (an object) and a pointer to
* the next node in the list.
*/
class Node
{
public Object data;
public Node next;
}
/** Reverses Contents in the linked List */
public void reverse() {
if (first ==null) {return;}
Node primary = first;
Node current = primary;
Node previous = null;
while (current!= null) {
Node next = current.next;
current.next= previous;
previous = current;
current = next;
}
first = previous;
}
/** Gives the size of the linked List*/
public void size() {
Node element = first;
int elementIndex = 0;
if (first == null) {System.out.println(0);}
else {
while (element!= null){
element = element.next;
elementIndex++;}
}
System.out.println(elementIndex);
}
/** Helper method for get(int n) method */
private Node getNode(int n) {
int index;
Node element = first;
for (index =0; index < n; index++) {
element = element.next;
}
return element;
}
/** Returns the nth element in the linked list */
public Object get(int n) {
return getNode(n).data;
}
/** Sorts the linked List*/
public void sort(Node node) {
}
public Object findElement(Object element){
}
public void print(Node node) {
if (node == null) {node =first;}
while (node!= null) {
System.out.println(node.data);
node = node.next;
}
}
public class ContactComparator implements Comparator<Contact1>{
#Override
public int compare(Contact1 a, Contact1 b)
{
return b.getName().charAt(0)-(a.getName().charAt(0));
}
}
public static void main (String [] args) {
list.addFirst(new Contact1("John Harvey" ,6000, "jh#gmail.com"));
list.addFirst(new Contact1("Cris Irish",2000, "cI#gmail.com"));
list.addFirst(new Contact1("Tom Jhonson",2400,"tj#gmail.com" ));
System.out.println("Current List:");
list.print(null);
list.reverse();
System.out.println("Reverse List: ");
list.print(null);
System.out.println("Size of the list");
list.size();
System.out.println("Current Size of the List");
System.out.println(list.currentSize);
list.get(1);
}
}
Here's the contact class:
package project3;
public class Contact1 {
private String name;
private int number;
private String mail;
public Contact1(String n, int pn, String e){
this.name= n;
this.number = pn;
this.mail =e;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getEmail() {
return mail;
}
public void setEmail(String name) {
this.mail = name;
}
public String toString(){
return "Name: "+this.name+" "+" Number "+this.number+" Email: " +this.mail;
}
From the look of it, you list has a natural order, so why don't you use a TreeSet instead of a list? In a set any entry must be unique and a tree set is ordered. Then your Contact1 class could implement Comparable and implement the Comparator itself.
I've been working on the exercise to better understand Linked List.
My output is:
***DISPALY NAMES
Miki
null
Arek
null
Magi
null
Problem: display nulls between names.
Tried to do: Wrote bunch of print statements and it looks like is adding extra Name reference object to the list. I was trying to find error in the add method but logically everything fines for me.
I am not allowed to use LinkedList API.
Thank you for your help.
<pre> <code>
public class NameTest {
public static void main(String[] args) {
NameList<Name> n = new NameList<Name>();
Name n1 = new Name(1,"Miki");
Name n2 = new Name(2, "Arek");
Name n3 = new Name(3, "Magi");
n.addName(n1);
n.addName(n2);
n.addName(n3);
n.displayNames();
System.out.println("*******************\n");
}
}
public class Name {
private int nameId;
private String firstName;
private Name next;
public Name() { }
public Name(int nameId, String firstName) {
super();
this.nameId = nameId;
this.firstName = firstName;
this.next = new Name();
}
public int getNameId() {
return nameId;
}
public void setNameId(int nameId) {
this.nameId = nameId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Name getNext() {
return next;
}
public void setNext(Name next) {
this.next = next;
}
}
public class NameList<T extends Name> {
private T head;
private int value;
public NameList() {
head = null;
value = 0;
}
public T getHead() {
return head;
}
public void setHead(T head) {
this.head = head;
}
public void addName(T name) {
if(head == null) {
setHead(name);
value++;
}
else {
T curr = getHead();
while(curr.getNext() != null) {
curr = (T) curr.getNext();
}
curr.setNext(name);
value++;
}
}
public void displayNames() {
System.out.println("***DISPLAY NAMES ");
T curr = getHead();
while(curr.getNext() != null ) {
System.out.println(curr.getFirstName());
curr = (T) curr.getNext();
}
if(curr.getNext() == null) {
System.out.println(curr.getFirstName());
}
}
Instance variable next in the class name should be like this: private Name next; I am sorry for confusion. I made correction in the code above.
Your problem is this line.
this.next = new Name();
You're adding a new "empty object" onto the back of every Name that you add. Remove it and you'll get the desired result. (I assume you also have Name extends Employee in there somewhere, otherwise this doesn't compile).