So I'm fairly new to Java and programming and I was wondering how to create a node class?
So far I have:
public class ItemInfoNode{
private ItemInfoNode next;
private ItemInfoNode prev;
private ItemInfo info;
public ItemInfoNode(ItemInfo info, ItemInfoNode next, ItemInfoNode prev){
info = info;
next = next;
prev = prev;
}
public void setInfo(ItemInfo info){
info = info;
}
public void setNext(ItemInfoNode node){
next = node;
}
public void setPrev(ItemInfoNode node){
prev = node;
}
public ItemInfo getInfo(){
return info;
}
public ItemInfoNode getNext(){
return next;
}
public ItemInfoNode getPrev(){
return prev;
}
}
Pretty much the question asked for those methods so I put those down but, the next question asks me to refer to the head and tail of ItemInfoNode nodes. Just a bit confused here. Thanks
EDIT: Thanks for the help guys! I'm trying to create an "InsertInfo" method that puts information like the name, price, tag number, etc. Into one node. How do I go about creating this method?
So far I got this.. I have an Iteminfo constructor in a different class that has all of these but, I'm not sure how to use that/if I am even supposed to do..
public void InsertInfo(String name, String rfdnumber, double price, String original_position){
head = new ItemInfoNode (Iteminfo, head);
}
Welcome to Java!
This Nodes are like a blocks, they must be assembled to do amazing things!
In this particular case, your nodes can represent a list, a linked list, You can see an example here:
public class ItemLinkedList {
private ItemInfoNode head;
private ItemInfoNode tail;
private int size = 0;
public int getSize() {
return size;
}
public void addBack(ItemInfo info) {
size++;
if (head == null) {
head = new ItemInfoNode(info, null, null);
tail = head;
} else {
ItemInfoNode node = new ItemInfoNode(info, null, tail);
this.tail.next =node;
this.tail = node;
}
}
public void addFront(ItemInfo info) {
size++;
if (head == null) {
head = new ItemInfoNode(info, null, null);
tail = head;
} else {
ItemInfoNode node = new ItemInfoNode(info, head, null);
this.head.prev = node;
this.head = node;
}
}
public ItemInfo removeBack() {
ItemInfo result = null;
if (head != null) {
size--;
result = tail.info;
if (tail.prev != null) {
tail.prev.next = null;
tail = tail.prev;
} else {
head = null;
tail = null;
}
}
return result;
}
public ItemInfo removeFront() {
ItemInfo result = null;
if (head != null) {
size--;
result = head.info;
if (head.next != null) {
head.next.prev = null;
head = head.next;
} else {
head = null;
tail = null;
}
}
return result;
}
public class ItemInfoNode {
private ItemInfoNode next;
private ItemInfoNode prev;
private ItemInfo info;
public ItemInfoNode(ItemInfo info, ItemInfoNode next, ItemInfoNode prev) {
this.info = info;
this.next = next;
this.prev = prev;
}
public void setInfo(ItemInfo info) {
this.info = info;
}
public void setNext(ItemInfoNode node) {
next = node;
}
public void setPrev(ItemInfoNode node) {
prev = node;
}
public ItemInfo getInfo() {
return info;
}
public ItemInfoNode getNext() {
return next;
}
public ItemInfoNode getPrev() {
return prev;
}
}
}
EDIT:
Declare ItemInfo as this:
public class ItemInfo {
private String name;
private String rfdNumber;
private double price;
private String originalPosition;
public ItemInfo(){
}
public ItemInfo(String name, String rfdNumber, double price, String originalPosition) {
this.name = name;
this.rfdNumber = rfdNumber;
this.price = price;
this.originalPosition = originalPosition;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRfdNumber() {
return rfdNumber;
}
public void setRfdNumber(String rfdNumber) {
this.rfdNumber = rfdNumber;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getOriginalPosition() {
return originalPosition;
}
public void setOriginalPosition(String originalPosition) {
this.originalPosition = originalPosition;
}
}
Then, You can use your nodes inside the linked list like this:
public static void main(String[] args) {
ItemLinkedList list = new ItemLinkedList();
for (int i = 1; i <= 10; i++) {
list.addBack(new ItemInfo("name-"+i, "rfd"+i, i, String.valueOf(i)));
}
while (list.size() > 0){
System.out.println(list.removeFront().getName());
}
}
Related
I am currently writing a program that creates Students and stores them in a doubly linked list based on their natural order (Last name, First name, GPA, then student ID). I am just starting off with generics and how they work so I am a little lost. I believe most of my code is working; the only part I need help with is adding students (who have multiple data types) into my list in my main method in my doubly linked list class. Any help is greatly appreciated! Here is my student, doubly linked list, and node class along with a fragment of the input file I am reading from with the data of each student:
Student class:
public class Student{
long studentID;
String firstName;
String lastName;
float GPA;
public Student(String lastName, String firstName, float GPA, long studentID){
this.lastName = lastName;
this.firstName = firstName;
this.GPA = GPA;
this.studentID = studentID;
}
public int compareTo(Student s){
int result = this.lastName.compareTo(s.lastName);
if(result == 0){
result = this.firstName.compareTo(s.firstName);
if(result == 0){
result = Float.compare(this.GPA, s.GPA);
if(result == 0){
result = Long.compare(this.studentID, s.studentID);
}
}
}
return result;
}
public String toString(){
return this.lastName + ", " + this.firstName +
" GPA: " + this.GPA + " ID: " + this.studentID;
}
}
Node class:
public class Node<T>{
Node<T> previous;
Node<T> next;
Student data;
public Node(Student data){
this(data, null, null);
}
public Node(Student data, Node<T> previous, Node<T> next){
this.data = data;
this.previous = previous;
this.next = next;
}
}
Doubly Linked List class:
import java.io.*;
import java.util.*;
import csci1140.*;
public class DoublyLinkedList<T> implements Iterable<Node>{
private Node root;
private Node tail;
private Node previous;
private class ListIterator implements Iterator<Node>{
Node current = root;
public boolean hasNext(){
return (current != null);
}
public Node next(){
Node answer;
answer = current;
current = current.next;
return answer;
}
}
public Iterator<Node> iterator(){
ListIterator listIterator = new ListIterator();
return listIterator;
}
public void add(T data){
Node<Student> newNode = new Node<Student>(data);
if(root == null){
root = newNode;
tail = root;
return;
}
Node current = root;
for( ; current!= null; current = current.next){
if(newNode.data.compareTo(current.data)<= 0){
break;
}
}
if(previous == null){
previous.next = newNode;
newNode.next = current;
if(current == null){
tail = newNode;
}
} else {
newNode.next = root;
root = newNode;
}
}
public static final void main(String[] args){
FileInputStream fileIn = null;
try{
fileIn = new FileInputStream("student_input.txt");
System.setIn(fileIn);
} catch(FileNotFoundException fnfe){
fnfe.printStackTrace(System.err);
}
//Do work here to create list of students
}
try{
fileIn.close();
} catch(Exception e){}
}
}
Student_input.txt:
1000
Lisa
Licata
2.28
1001
Shelley
Santoro
1.56
1002
Ok
Ota
3.33
1003
Cindi
Caggiano
1.65
Still not completely sure, maybe some variation of this.
Especially this inserts before the first Node that is bigger, and I am still not sure what the generics are for in this case and T needs to be something that extends Student(well it needs the compareTo method):
public void add(T data) {
for(Node<T> current = root; current != null; current = current.next) {
if (data.compareTo(current.data) <= 0) {
current = new Node<>(data,current.previous,current);
if(null == current.previous){
root = current;
}else {
current.previous.next = current;
}
if(null == current.next){
tail = current;
} else {
current.next.previous = current;
}
return;
}
}
tail = new Node<>(data,tail,null);
if(null == tail.previous) root=tail;
}
So your list should maybe look like this(to ensure T has the compareTo method):
public class DoublyLinkedList<T extends Student> implements Iterable<Node<T>> {
...
}
All together(To have Node as a seperate file like you do is better - but for brevity I put it into the list):
public class DoublyLinkedList<T extends Student> implements Iterable<Node<T>> {
public static class Node<S> {
Node<S> previous;
Node<S> next;
S data;
public Node(S data) {
this(data, null, null);
}
public Node(S data, Node<S> previous, Node<S> next) {
this.data = data;
this.previous = previous;
this.next = next;
}
}
private Node<T> root = null;
private Node<T> tail = null;
private class ListIterator implements Iterator<Node<T>> {
Node<T> current = root;
#Override
public boolean hasNext() {
return (current != null);
}
#Override
public Node<T> next() {
Node<T> answer;
answer = current;
current = current.next;
return answer;
}
}
#Override
public Iterator<Node<T>> iterator() {
ListIterator listIterator = new ListIterator();
return listIterator;
}
public void add(T data) {
for(Node<T> current = root; current != null; current = current.next) {
if (data.compareTo(current.data) <= 0) {
current = new Node<>(data,current.previous,current);
if(null == current.previous){
root = current;
}else {
current.previous.next = current;
}
if(null == current.next){
tail = current;
} else {
current.next.previous = current;
}
return;
}
}
tail = new Node<>(data,tail,null);
if(null == tail.previous) root=tail;
}
}
Node
private Object data;
private Node link;
private Node next;
private Node prev;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getLink() {
return link;
}
public void setLink(Node link) {
this.link = link;
}
public Node(Object data) {
this.data = data;
this.link = null;
}
public Node getNextNode() {
return next;
}
public Node getPrevNode() {
return prev;
}
public void setNextNode(Node n) {
next = n;
}
public void setPrevNode(Node n) {
prev = n;
}
Item
private int id;
private String name;
private String type;
private double price;
public Item(int id, String name, String type, double price) {
this.id = id;
this.name = name;
this.type = type;
this.price = price;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public double getPrice() {
return price;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setType(String type) {
this.type = type;
}
public void setPrice(double price) {
this.price = price;
}
#Override
public String toString() {
return "Item: " + "ID: " + id + ", Name: " + name + ", Type: " + type + ", Price: " + price;
}
LinkedList
private Node head; // first node in the linked list
private int count;
public int getCount() {
return count;
}
public Node getHead() {
return head;
}
public LinkedList() {
head = null; // creates an empty linked list
count = 0;
}
public void addFront(int n) {
Node newNode = new Node(n);
newNode.setLink(head);
head = newNode;
count++;
}
public void deleteFront() {
if (count > 0) {
head = head.getLink();
count--;
}
}
public void AddItemToFront(Item p) {
Node newNode = new Node(p);
newNode.setLink(head);
head = newNode;
count++;
}
public void DisplayItems() {
Node temp = head;
while(temp != null) {
System.out.println(temp.getData());
temp = temp.getLink();
}
}
public void RemoveItemAtPosition(int n) {
if(n == 1) {
Node x = head;
head = x.getLink();
count--;
}
else if (n > count || n < 0) {
System.out.println("The index you entered is out of bound.");
}
else {
Node x = head;
for (int i = 1; i < n; i++) {
x = x.getNextNode();
}
Node temp = x;
x = temp.getPrevNode();
x.setNextNode(temp.getNextNode());
temp = null;
count--;
}
}
I'm trying to remove a Node at a position given integer n.
I tried researching on SO before posting here and the above is the code that i came out with. However, the code returned me an error saying >java.lang.NullPointerException at LinkedList.java:74 at main:35
The Node is actually an object that is being added to the LinkedList
I checked your code I see that you have some bugs.
your mistakes are:
1 -you use linked object.
2- try to access previous and next without initialization.
3- you only care on the next node.
I removed link form Node class and I do some changes into LinkedList:
public class LinkedList {
private Node head; // first node in the linked list
private int count;
public int getCount() {
return count;
}
public Node getHead() {
return head;
}
public LinkedList() {
head = null; // creates an empty linked list
count = 0;
}
public void addFront(int n) {
Node newNode = new Node(n);
if (head == null) {
head = newNode;
} else {
Node node = head;
head = newNode;
head.setNextNode(node);
node.setPrevNode(head);
}
count++;
}
public void deleteFront() {
if (count > 0) {
head = head.getNextNode();
head.setPrevNode(null);
count--;
}
}
public void AddItemToFront(Item p) {
Node newNode = new Node(p);
if (head == null) {
head = newNode;
} else {
Node node = head;
head = newNode;
head.setNextNode(node);
node.setPrevNode(head);
}
count++;
}
public void DisplayItems() {
Node temp = head;
while (temp != null) {
System.out.println(temp.getData());
temp = temp.getNextNode();
}
}
public void RemoveItemAtPosition(int n) {
if (n == 1) {
deleteFront();
} else if (n > count || n < 0) {
System.out.println("The index you entered is out of bound.");
} else {
Node x = head;
for (int i = 1; i < n; i++) {
x = x.getNextNode();
}
Node temp = x;
temp.getPrevNode().setNextNode(temp.getNextNode());
temp.getNextNode().setPrevNode(temp.getPrevNode());
temp = null;
count--;
}
}
}
When checking the provided source code, in the function AddItemToFront(Item p) only the linked-list is managed with newNode.setLink(head);. Both Node next; and Node prev; are never initialized and never used before in the function removeItemAtPosition(int n).
Warning: your Linked-List is managed on reverse (due to the function void AddItemToFront(Item p)).
A simple way to solve your problem should to use only Node link; also in the function removeItemAtPosition(int n).
Step 1 - in RemoveItemAtPosition(int n), modify the search of the nth Node in the for-loop
Node x = head;
for (int i = 1; i < n; i++) {
x = x.getLink(); // Use Node link
}
Instead of
Node x = head;
for (int i = 1; i < n; i++) {
x = x.getNextNode();
}
Step 2 - in RemoveItemAtPosition(int n), connect the next node link to the node before
Node temp = x.getLink();
x.setLink(temp.getLink());
count--;
Instead of
Node temp = x;
x = temp.getPrevNode();
x.setNextNode(temp.getNextNode());
temp = null;
count--;
I have made a queue of a generic type. When I try to print out the contents of the two queues I have created the result is returned in the format of the last element in is the first element out (LIFO) instead of first in first out (FIFO). I can't seem to get it to print in the right order(FIFO). I use three separate classes. The MyNode class:
public class MyNode<T> {
public T payload;
public MyNode<T> next;
public MyNode<T> previous;
public MyNode(T payload) {
this.payload = payload;
}
public MyNode(T payload, MyNode<T> next, MyNode<T> previous) {
this.payload = payload;
this.next = next;
this.previous = previous;
}
public T getPayload() {
return payload;
}
public MyNode<T> getNext() {
return next;
}
public MyNode<T> getPrevious() {
return previous;
}
public void setPayload(T payload) {
this.payload = payload;
}
public void setNext(MyNode<T> next) {
this.next = next;
}
public void setPrevious(MyNode<T> previous) {
this.previous = previous;
}
}
The TestQueue class:
public class TestQueue {
public static void main(String[] args) {
MyQueue<String> qStr = new MyQueue<String>();
MyQueue<Integer> qInt = new MyQueue<Integer>();
qStr.enqueue("hello");
qStr.enqueue("world");
System.out.println("Size of queue: " + qStr.size());
System.out.println(qStr);
System.out.println();
qInt.enqueue(42);
qInt.enqueue(3);
System.out.println("Size of queue: " + qInt.size());
System.out.println(qInt);
System.out.println();
qStr.dequeue();
System.out.println(qStr);
System.out.println();
qInt.dequeue();
System.out.println(qInt);
}
}
The MyQueue class:
public class MyQueue<T> {
public int size = 0;
public MyNode<T> front = new MyNode<T>(null);
public MyNode<T> back = new MyNode<T>(null);
public void enqueue(T payload) {
MyNode<T> newNode = new MyNode<T>(payload);
newNode.next = front;
front = newNode;
if (isEmpty()) {
back = newNode;
}
size++;
}
public T dequeue() {
if (isEmpty()) {
return null;
}
T payload = front.payload;
front = front.getNext();
size--;
return payload;
}
public boolean isEmpty() {
return front == null;
}
public int size() {
return size;
}
public String toString() {
return front.getPayload().toString();
}
}
You're inserting the new guys at the front of the queue instead of the back. The problem is with:
newNode.next = front;
//back.next = null;
front = newNode;
what you should do is:
Node tmp = front;
while (tmp.next != null) tmp = tmp.next;
tmp.next = newNode;
I'll leave the updating of the previous field and size to you.
The problem comes in the toString method of the following code:
import java.util.*;
public class LinkedDeque<T> // implements Deque<T>
{
private Node head;
private Node tail;
private int size;
private class Node // Node class
{
T info;
Node next;
Node prev;
private Node (T info, Node prev, Node next)
{
this.info = info;
this.prev = prev;
this.next = next;
}
private T getInfo()
{
return this.info;
}
private Node getNext()
{
return this.next;
}
private Node getPrev()
{
return this.prev;
}
}
public LinkedDeque ()
{
this.head = null;
this.tail = null;
this.size = 0;
}
public static void main()
{
}
public int size ()
{
Node count = head;
while(count.getNext() != null)
{
size++;
count = count.getNext();
}
return size;
}
public String toString()
{
return this.getInfo();
}
public boolean isEmpty()
{
return size() == 0;
}
}
My compiler keeps giving me an error saying that the getInfo method is missing. Any help would be appreciated! Initially, I thought this was due to the fact that the Node class was private, but the Node getNext() method works fine in the method size().
The toString method is a member of LinkedDeque not Node. LinkedDeque does not have a getInfo method.
Not sure what it is you were trying to achieve, but you may consider moving that method into the Node class...
Hello There I am trying to test removeCity(), but it didn't remove any element that I provide.
also the method addToList() if I use it in the City class I get "Exception in thread "main" java.lang.StackOverflowError" while it work fine in the test class
Any help ?
MyList
public class MyList<T> {
private Node head;
private Node tail;
public MyList(){
head = null;
tail = null;
}
public void addToTail(T info){
Node n;
//case 1: empty List
if(isEmpty()){
n = new Node(info, null);
head = n;
tail = head;
}
//case 2: if the list is not empty
else {
n = new Node(info, null);
tail.setNext(n);
tail = n;
}
}
public void addToHead(T info){
Node n;
//case 1: empty List
if(isEmpty()){
n = new Node(info, null);
head = n;
tail = head;
}
//case 2: if the list is not empty
else {
n = new Node(info, head);
head = n;
}
}
public boolean removeHead(){
//Case 1: if the list is empty
if(isEmpty())
return false;
//case 2: if the list have at least one element
else{
Node n = head.getNext();
head = n;
return true;
}
}
public boolean removeElement(String element){
//cacs 1 if before is the head
if(isEmpty())
return false;
if( ((City) head.getInfo()).getCode().equals(element)){
removeHead();
return true;
}
Node iter = head.getNext();
Node prev = head;
while(iter != null && !((City) head.getInfo()).getCode().equals(element)){
iter = iter.getNext();
prev = prev.getNext();
}
if(iter == null)
return false;
else{
prev.setNext(iter.getNext());
return true;
}
}
//To check if the list is empty
public boolean isEmpty(){
if ( head == null)
return true;
else
return false;
}
Node
public class Node<T> {
private T info;
private Node next;
public Node(){
info = null;
next = null;
}
public Node(T info, Node next){
this.info = info;
this.next = next;
}
public T getInfo(){
return info;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
public void setInfo(T info){
this.info = info;
}
}
City
public class City implements Serializable {
public static MyList<City> cityList = new MyList<City>();
private String name;
private String code;
public City(String name, String code) {
super();
this.name = name;
this.code = code;
addToList(new City(name,code));
}
public void addToList(City toAdd){
City.cityList.addToHead(toAdd);
}
public static void removeCity(String name){
if( cityList.isEmpty()){
System.out.println("The List is empty");
return;
}
if ( cityList.removeElement(name) == true )
System.out.println("The City was removed sucssesfully");
else
System.out.println("This city does not not exist");
}
}
Test
public class DummyTest {
public static void main(String [] args){
City x = new City("Ney York","NY");
City y = new City("London","LD");
System.out.println(City.cityList);
}
}
Stacktrace
Exception in thread "main" java.lang.StackOverflowError
at City.<init>(City.java:15)
at City.<init>(City.java:18)
at City.<init>(City.java:18)
Line 15 is the constructor
public City(String name, String code)
Line 18 is addToList
addToList(new City(name,code))
What I've spotted that you have an issue in your while loop in removeElement method.
I am not sure if it will solve your issue.
Could you also put a part of stacktrace here were do you get StackOverflowException.
Node iter = head.getNext();
Node prev = head;
while(iter != null && !((City) head.getInfo()).getCode().equals(element)){
iter = iter.getNext();
prev = prev.getNext();
}
this line
while(iter != null && !((City) head.getInfo()).getCode().equals(element))
should be probably
while(iter != null && !((City) iter.getInfo()).getCode().equals(element))
iter instead head
Alexey already found the first error, here are 2 more:
public City(String name, String code) {
super();
this.name = name;
this.code = code;
addToList(new City(name,code)); // <- infinite recursion
}
is infinite recursion: the (constructor-)method calls the (constructor-)method.
It should probably be addToList(this);
Also: In mylist.java all the new Node(..) should be new Node<T>(..).