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>(..).
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;
}
}
I am doing an library inventory system, so I was supposed to sort the name inside the Node into alphabetical order. I have bookname, author, isbn number, number of copies and genre, all these information I store inside a class.
I do wrote the code for it to sort alphabetically, but it didn't work.
Could someone tell me what's wrong in my code?
Here is my Linked List class contain insert and display method:
public class LinkedList
{
Node node = new Node();
static Node head;
public LinkedList()
{
head=null;
}
public Node getHead()
{
return head;
}
public static void addNode(Data data)
{
Node newNode = new Node(data, head);
if (head == null) {
head = newNode;
newNode.setNext(null);
} else {
Node next = head;
Node prev = next;
do {
if (data.name.compareTo(next.data.name) < 0) {
break;
}
prev = next;
next = next.getNext();
} while (next != null);
newNode.setNext(next);
if (data.name.compareTo(next.data.name) < 0) {
head = newNode;
} else prev.setNext(newNode);
}
}
public static String displayNode()
{
Node current = head;
String output = "";
while(current != null){
output+=current.data.toString();
current = current.next;
}
return output;
}
Here is my Node class:
public class Node
{
Data data;
Node next;
public Node()
{
next = null;
}
Node(Data data, Node next)
{
this.data = data;
this.next = next;
}
public Object getData()
{
return data;
}
public Node getNext()
{
return next;
}
public void setNext(Node next)
{
this.next=next;
}
}
Here is my Data class:
public class Data {
LinkedList list;
String name;
String author;
int isbn;
int number;
String genre;
public Data(String name, String author, int isbn, int number, String genre)
{
this.name = name;
this.author = author;
this.isbn = isbn;
this.number = number;
this.genre = genre;
}
public String toString()
{
return("Book Name: "+name+"\nAuthor: "+author+"\nISBN Number: "+isbn+"\nNumber of Copies: "+number+"\nGenre: "+genre+"\n\n");
}
public String getName()
{
return name;
}
Here is my Iterator class which I used to display the list:
public class DisplayIterator
{
LinkedList list;
static Node current;
static Node newNode;
DisplayIterator(Node newNode)
{
this.newNode = newNode;
current = list.head;
}
public static boolean hasNext()
{
if(current == null){
return false;
}
else if (current.next == null){
return false;
}
return true;
}
public static Node next()
{
if(hasNext()){
current = current.next;
}
return current;
}
public static void remove(){
throw new UnsupportedOperationException("It is read-only.");
}
}
Thank you.
The following code implements an order based insertion into a linked list. This of course assumes that the list is already sorted. It is safe to make this assumption because the only way in your interface to add nodes to a linked list is via this method.
public static void addNode(Data data) {
Node newNode = new Node(data, head);
if (head == null) {
head = newNode;
return;
}
Node current = head;
while (current.next != null && data.name.compareTo(current.data.name) >= 0) {
current = current.next;
}
if (current == head && data.name.compareTo(current.data.name) < 0) {
newNode.next = head;
head = newNode;
}
else {
newNode.next = current.next;
current.next = newNode;
}
JOptionPane.showMessageDialog(null,"Book Information has been added to the inventory.");
}
I assume, your Node is not the one from java util LinkedList, right? Can you provide the implementation of it? Why does its constructor the head ?
You insert your new element at the begin and try to traverse forward. And at the end of your loop in your current is the first greater and previous the last smaller. Until now correct.
But afterwards, you never use the Previous, and sets the new element to your. You nead to insert it between previous and current. Something like that:
if (previous == null)
head = newData;
else
previous.next = newData;
newData.next = current;
Java has a rich library for sorting for any collection of data
java.util.Collections.sort(YOURLIST_valiable)
I'm trying to sort a linkedlist with generics but I'm having trouble with some casting issues. The code is throwing Bus can't be cast to Node. I know the problem is in the comparator (where I casted to Bus) but otherwise I don't know how could I call to the methods defined in Bus (irrelevant whether is Bus or another Object, just testing with a random one) . I've been researching the internet but couldn't find a solution. Here is the code:
/**
* Swaps the current node's element with the previous one
*/
public void swap(){
Object previous = getCurrent().getElement();
Object current = next().getElement();
getCurrent().setElement(previous);
previous().setElement(current);
}
public AbstractList<T> orderBy(Comparator<Node<T>> comparator){
setCurrent(getFirst());
Node<T> aux;
Node<T> current;
boolean check = true;
while (check){
check = false;
aux = getFirst();
current = getFirst().getNext();
while(hasNext()) {
if (comparator.compare(aux, current) > 0) {
check = true;
swap();
}
aux = current;
current = current.getNext();
}
}
return this;
}
The comparator:
import java.util.Comparator;
public class InternComparator implements Comparator<Node<Bus>>{
#Override
public int compare(Node<Bus> o1, Node<Bus> o2) {
return ((Bus)o1.getElement()).getIntern() - ((Bus)o2.getElement()).getIntern();
} //getIntern() returns an Integer
AbstractList (given by the professor):
import java.util.NoSuchElementException;
public class AbstractList<T> {
private Node<T> first;
private Node<T> current;
private Node<T> last;
private int size = 0;
public boolean hasNext(){
return current != last;
}
public boolean hasPrevious(){
return current != first;
}
public Node getCurrent(){
return current;
}
public void setCurrent(Node<T> current) {
this.current = current;
}
public int size(){
return size;
}
public boolean isEmpty(){
return first == last || first == null;
}
public void add(T t){
Node<T> a = new Node<T>(t);
if(first == null){
first = a;
}
if(last == null && first != null){
last = a;
last.setPrevious(first);
first.setNext(last);
}
Node<T> aux = last;
last.setNext(a);
last = a;
last.setPrevious(aux);
current = last;
size++;
}
public Node next(){
if(!hasNext()){
throw new RuntimeException("No elements available next.");
}
current = current.getNext();
return current;
}
public Node previous(){
if(!hasPrevious()){
throw new RuntimeException("No elements available previous.");
}
current = current.getPrevious();
return current;
}
public Node getFirst(){
return first;
}
public Node getLast(){
return last;
}
public void setFirst(Node<T> first){
this.first = first;
}
public void setLast(Node<T> last) {
this.last = last;
}
public void remove(T t){
current = first;
boolean removed = false;
while (hasNext()) {
if (current.getElement() == t || current.getElement().equals(t)) {
if(current != last && current != first) {
current.getNext().setPrevious(current.getPrevious());
current.getPrevious().setNext(current.getNext());
} else if(current == first){
current.getNext().setPrevious(null);
} else if(current == last){
current.getPrevious().setNext(null);
}
removed = true;
return;
}
current = next();
}
if(removed){
size--;
} else {
throw new NoSuchElementException("No such element on the list.");
}
}
public Node goTo(int pos){
if(pos > size){
throw new ArrayIndexOutOfBoundsException("Inexistent Position");
}
current = first;
for(int i = 0; i < pos; i++){
current = next();
}
return current;
}
public void insertAfter(T t){
Node<T> aux = new Node<>(t);
if(current != last) {
Node<T> next = current.getNext();
Node<T> previous = current;
current.getNext().setPrevious(aux);
current.setNext(aux);
aux.setNext(next);
aux.setPrevious(previous);
} else {
current.setNext(aux);
aux.setPrevious(current);
last = aux;
}
size++;
}
public void insertPrevious(T t){
Node<T> aux = new Node<>(t);
if(current != first) {
Node<T> previous = current.getPrevious();
Node<T> next = current;
current.getPrevious().setNext(aux);
current.setPrevious(aux);
aux.setNext(next);
aux.setPrevious(previous);
} else {
Node<T> aux1 = current;
current.setPrevious(aux);
first = aux;
first.setNext(aux1);
}
size++;
}
#Override
public String toString() {
String result = "";
current = first;
while(hasNext()) {
result += current.getElement() + "";
next();
}
return result;
}
}
class Node<T> {
private Object element;
private Node<T> prev;
private Node<T> next;
public Node(T element){
this.element = element;
}
public Node(T element, Node next){
this.element = element;
this.next = next;
}
public Node<T> getNext() {
return next;
}
public Node<T> getPrevious() {
return prev;
}
public Object getElement() {
return element;
}
public void setNext(Node<T> next) {
this.next = next;
}
public void setPrevious(Node<T> prev) {
this.prev = prev;
}
public void setElement(Object element) {
this.element = element;
}
}
Think again: your object is of type Node<Bus>; and you are wondering why the cast to Bus fails?
Or lets rephrase: do you assume that a Bus<People> represents a human being?
If you have a container, then you have to retrieve the contained value; and that can't be achieved by casting the container!
Or, to keep using strange pictures: you don't get an egg out of the box by declaring the box to be an egg. You open the box, and fetch the egg.
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());
}
}
I have implemented a priority queue using a linked list. In this priority queue the smallest int value has the highest value and therefore by calling the remove method the smallest method will be removed.
Code for Node Class
public class Node {
public int iData;
public Node next;
public Node(int x) {
iData = x;
}
public void displayNode() {
System.out.println(iData + " ");
}
}
Code for Link List
public class LinkList {
private Node first;
public LinkList() {
first = null;
}
public boolean isEmpty() {
return first == null;
}
public void insert(int x) {
Node newNode = new Node(x);
Node previous = null;
Node current = first;
while (current != null && x < current.iData) {
previous = current;
current = current.next;
}
if (previous == null) {
newNode.next = first;
first = newNode;
}
else {
previous.next = newNode;
newNode.next = current;
}
}
public Node remove() {
Node previous = null;
Node current = first;
Node temp = current;
while (current.next != null) {
previous = current;
current = current.next;
}
previous.next = null;
return temp;
}
public void display() {
Node current = first;
while (current != null) {
current.displayNode();
current = current.next;
}
System.out.println(" ");
}
}
Code for Priority Queue
public class PriorityQ {
private LinkList list;
public PriorityQ() {
list = new LinkList();
}
public void insert(int x) {
list.insert(x);
}
public void remove() {
list.remove();
}
public void displayList() {
System.out.println("Largest Value to Smallest");
list.display();
}
}
It is working fine at the moment, however i am not sure if my remove method in the link list class is the best way to go about removing elements. So i am looking for suggestions.
remove() is supposed to remove the first element from the list, right? Why do you loop anything for that?
Since your list is singly-linked (only pointing to next elements in the Node) all you need to do is:
Store the first in a temporary variable (if it's != null)
Then update first to be pointing to the 2nd item in the list
(first.next if != null)
Then return the temporary variable.
This can be implemented by having single pointer to first node and maintaining order by storing the smallest element to the first node.
public class LinkedListBasedOrderedMinPQ<T extends Comparable<T>> implements PriorityQueue<T> {
private Node<T> head;
private int size;
//Maintains an ordered linked list with the min element as the head
#Override
public void insert(T item) {
Node<T> node = head;
head = insert(node, item);
}
private Node<T> insert(Node<T> node, T item) {
Node<T> newNode = createNewNode(item);
if(null == node) {
return newNode;
}
if(node.data.compareTo(item) > 0) {
newNode.next = node;
node = newNode;
} else {
node.next = insert(node.next, item);
}
return node;
}
private Node<T> createNewNode(T item) {
size++;
return new Node<T>(item);
}
#Override
public T remove() {
if(null == head) {
return null;
}
T data = head.data;
head = head.next;
size--;
return data;
}
#Override
public int size() {
return size;
}
private static class Node<T> {
private final T data;
private Node<T> next;
public Node(T data) {
this.data = data;
}
#Override
public String toString() {
return "Node [data=" + data + ", next=" + next + "]";
}
}
}