LinkedList program unresponsive; possible null pointer error - java

Alright, so I hate to ask for help on a problem so vague, but I'm working on a project right now that doesn't seem to be getting any compile-time errors, yet won't do what's asked of it. To sum it up simply, this project is a linked list(unordered list, to be specific) that functions as a text editor. It takes in a file as a command line argument, then stores every separate line of the document as a node in the list. Whether it's doing that for sure or not I don't know, but after that the program takes in specific commands(keyboard input) and edits or lists the text of the file as requested.
The problem is, I can't even tell if the file is being stored in the list or not because every time I give the command L for list, the program just 'skips' it and continues on as if nothing was asked of it. It may be that the file isn't being stored for whatever reason, or there may be an issue with the toString method of the unorderedList class.
The code for all of my classes is as follows:
public class LinearNode<T> {
//Begin by declaring the basic node and its data
private LinearNode<T> next;
private T element;
public LinearNode() {
//The basic null constructor
next = null;
element = null;
}
public LinearNode(T elem) {
//The overloaded constructor to create a node
next = null;
element = elem;
}
public LinearNode<T> getNext() {
//Get the node reference
return next;
}
public void setNext(LinearNode<T> node) {
//Create or redirect a node reference
next = node;
}
public T getElement() {
//Get the actual data stored in the node
return element;
}
public void setElement(T elem) {
//Create or redirect the node's data
element = elem;
}
}
And for the lists
public abstract class LinkedList<T> implements ListADT<T>, UnorderedListADT<T> {
protected int count;
protected LinearNode<T> head, tail;
protected int modCount;
public LinkedList () {
count = 0;
head = null;
tail = null;
head = tail;
head.setNext(tail);
modCount = 0;
}
public T remove(T targetElement) throws EmptyCollectionException, ElementNotFoundException {
if(isEmpty())
throw new EmptyCollectionException("LinkedList");
boolean found = false;
LinearNode<T> previous = null;
LinearNode<T> current = head;
while(current!=null&&!found) {
if(targetElement.equals(current.getElement())) {
found = true;
}
else {
previous = current;
current = current.getNext();
}
}
if(!found)
throw new ElementNotFoundException("Linked List");
if(size()==1) {
head = tail = null;
}
else if(current.equals(head))
head = current.getNext();
else if(current.equals(tail)) {
tail = previous;
tail.setNext(null);
}
else {
previous.setNext(current.getNext());
}
count--;
modCount++;
return current.getElement();
}
}
 
import java.util.Iterator;
public class UnorderedList<T> extends LinkedList<T>{
public UnorderedList() {
super();
}
public void addToFront(T element) {
if(head==null) {
head = new LinearNode<T>(element);
if(tail==null) {
tail = head;
}
count++;
modCount++;
}
else {
LinearNode<T> current = head;
head.setElement(element);
head.setNext(current);
count++;
modCount++;
}
}
public void addToRear(T element) {
if(tail.getElement()==null) {
tail.setElement(element);
count++;
modCount++;
}
else {
LinearNode<T> current = tail;
tail = new LinearNode<T>(element);
current.setNext(tail);
count++;
modCount++;
}
}
public void addAfter(T element, T target) {
LinearNode<T> current = head;
LinearNode<T> node = new LinearNode<T>(element);
LinearNode<T> temp = null;
while(!(current.getElement()==target)) {
current = current.getNext();
}
if(!(current.getNext()==null)) {
temp = current.getNext();
//temp.setElement(current.getElement());
}
current.setNext(node);
node.setNext(temp);
count++;
modCount++;
}
public T removeLast() {
T last = tail.getElement();
tail = null;
LinearNode<T> current = head;
while(!(current.getNext()==null)) {
current = current.getNext();
}
current = tail;
count--;
modCount++;
return last;
}
public int size() {
return count;
}
public Iterator<T> iterator() {
Iterator<T> itr = this.iterator();
return itr;
}
public boolean isEmpty() {
boolean result = false;
if(head==null&&tail==null) {
result = true;
}
else
result = false;
return result;
}
public T first() {
return head.getElement();
}
public T last() {
return tail.getElement();
}
public boolean contains(T elem) {
boolean result = false;
for(T element : this) {
if(element==elem) {
result = true;
break;
}
}
return result;
}
public T removeFirst() {
LinearNode<T> current = head;
head = current.getNext();
count--;
modCount++;
return current.getElement();
}
public String toString() {
LinearNode<T> current = head;
String s = "";
for(int countA=0;countA<count;count++) {
s += (countA+1)+"> "+current.getElement()+"\n";
current = current.getNext();
}
return s;
}
}
and for the main editor
import java.util.Scanner;
import java.util.Iterator;
import java.io.*;
public class myEditor {
public static void saveToFile(String text, String filename) throws IOException{
PrintWriter out = new PrintWriter(new File(filename));
out.println(text);
out.close();
}
public static void main(String args[]) {
boolean quit = false;
try {
if(args.length!=1) {
throw new IllegalArgumentException();
}
String filename = args[0];
Scanner input = new Scanner(new File(filename));
//Add exception
UnorderedList<String> list = new UnorderedList<String>();
while(input.hasNextLine()) {
if(list.head==null) {
list.addToFront(input.nextLine());
}
list.addToRear(input.nextLine());
}
System.out.println(">");
do {
Scanner command = new Scanner(System.in);
String comm = command.next();
String[] comm1 = comm.split(" ");
if(comm1.length==1) {
if(comm1[0].equalsIgnoreCase("I")) {
System.out.println("Type a line of text >");
comm = command.next();
list.addToRear(comm);
}
else if(comm1[0].equalsIgnoreCase("L")) {
System.out.print(list.toString());
}
else if(comm1[0].equalsIgnoreCase("E")) {
saveToFile(list.toString(), filename);
quit = true;
break;
}
}
else {
if(comm1[0].equalsIgnoreCase("I")) {
int linNum = Integer.parseInt(comm1[1]);
Iterator<String> itr = list.iterator();
String current = "";
for(int count=0;count<linNum;count++) {
current = itr.next();
}
list.addAfter(comm, current);
}
else if(comm1[0].equalsIgnoreCase("D")) {
int linNum = Integer.parseInt(comm1[1]);
if(linNum<=list.count&&linNum>0) {
Iterator<String> itr = list.iterator();
String current = "";
for(int count=0;count<linNum;count++) {
current = itr.next();
}
list.remove(current);
}
}
}
}
while(!quit);
}
catch(IllegalArgumentException e) {
System.err.print(e.getMessage());
}
catch(FileNotFoundException e) {
System.err.print(e.getMessage());
}
catch(IOException e) {
System.err.print(e.getMessage());
}
}
}
There's a few other classes and some interfaces as well, but for the issue I'm experiencing, I don't think they're that relevant.
Does anyone see what might be happening here, or what I might have written wrong to cause my program to ignore the command?

Look at your LinkedList constructor
head = null;
tail = null;
head = tail;
head.setNext(tail);
head is null yet you call its setNext method, it should throw an NPE.

Related

Removing all instances of an element from a custom LinkedList

Im trying to remove all people from the list who have the same course name in my custom LinkedList class. I have managed to get my programme to delete people individually based on number however can not figure out how to remove multiple at once. I have browsed online for any solutions and have tried multiple so far but none to any success I also attempted one myself but also no success any help or links to were I could learn mode would be greatly appreciated. Below is my Driver, LinkedList, and LinearNode class. I have also removed code I beleive is not relevant to this solution :).
Linked List Class
public class LinkedList<T> implements LinkedListADT<T> {
private int count; // the current number of elements in the list
private LinearNode<T> list; //pointer to the first element
private LinearNode<T> last; //pointer to the last element
//-----------------------------------------------------------------
// Creates an empty list.
//-----------------------------------------------------------------
public LinkedList()
{
this.count = 0;
this.last = null;
this.list = null;
}
public void add (T element)
{
LinearNode<T> node = new LinearNode<T> (element);
if (size() == 0) {
this.last = node; // This is the last and the
this.list = node; // first node
this.count++;
}//end if
else
{
last.setNext(node); // add node to the end of the list
last = node; // now make this the new last node.
this.count++;
} //end else
}
public T remove()
{
LinearNode<T> current = list;
LinearNode<T> temp = list;
T result = null;
if (current == null) {
System.out.println("There are no such employees in the list");
}//end if
else {
result = this.list.getElement();
temp = list;
this.list = this.list.getNext();
temp.setNext(null); //dereference the original first element
count--;
}//end else
return result;
}
public T remove(T element)
{
LinearNode<T> current = list;
LinearNode<T> previous = list;
LinearNode<T> temp;
T result = null;
if (current == null) {
System.out.println("There are no such employees in the list");
}//end if
else {
for (current = this.list; current != null && !current.getElement().equals(element); current = current.getNext())
{
previous = current;
}
if(current == null) {
System.out.println("No such employee on the list");
}
else if (current == list)
{
remove();
}
else if(current == last) {
previous.setNext(null);
this.last = previous.getNext();
count--;
}
else
{
previous.setNext(current.getNext());
count--;
}
}
return result;
}
**
My attempted Solution**
public T clear(T element) {
T result = null;
while (this.list != null && this.list.getElement() == element) {
this.list = this.list.getNext();
count--;
}
if (this.list == null) {
return result;
}
LinearNode<T> current = this.list;
while (current.getNext() != null) {
if (current.getNext().getElement() == element) {
current.setNext(current.getNext());
count--;
} else {
current = current.getNext();
}
}
return result;
}
}
LinearNode Class
public class LinearNode<T>
{
private LinearNode<T> next;
private T element;
//---------------------------------------------------------
// Creates an empty node.
//---------------------------------------------------------
public LinearNode()
{
this.next = null;
this.element = null;
}
//---------------------------------------------------------
// Creates a node storing the specified element.
//---------------------------------------------------------
public LinearNode (T elem)
{
this.next = null;
this.element = elem;
}
//---------------------------------------------------------
// Returns the node that follows this one.
//---------------------------------------------------------
public LinearNode<T> getNext()
{
return this.next;
}
//---------------------------------------------------------
// Sets the node that follows this one.
//---------------------------------------------------------
public void setNext (LinearNode<T> node)
{
this.next = node;
}
//---------------------------------------------------------
// Returns the element stored in this node.
//---------------------------------------------------------
public T getElement()
{
return this.element;
}
//---------------------------------------------------------
// Sets the element stored in this node.
//---------------------------------------------------------
public void setElement (T elem)
{
this.element = elem;
}
}
Driver Class
public class TrainingCourses {
LinkedList<employee>list;
int Size =10;
int numberofEmployees=0;
public TrainingCourses() {
list = new LinkedList<employee>();
inputEmployee();
displayEmployee();
deleteCourses();
displayEmployee();
}
public void inputEmployee() {
employee a;
a = null;
String number,name,courseName = null;
int years;
Scanner scan = new Scanner(System.in);
for (int count = 1; count<=numberofEmployees; count++){
System.out.println("Input employee number");
number = scan.nextLine();
System.out.println("Input employee name");
name = scan.nextLine();
System.out.println("Input years at organisation");
years = scan.nextInt(); scan.nextLine();
if(years >=5) {
System.out.println("Input course name");
courseName = scan.nextLine();
}else {
System.out.println("Can not join training course employee must be with organisation 5 or more years");
}
a = new employee(number,name,years,courseName);
list.add(a);
}
}
public void displayEmployee() {
System.out.println("\nDisplaying all employees....");
System.out.println(list.toString());
}
public void deleteCourses(){
{
Scanner scan = new Scanner(System.in);
employee b = null;
String number,name,courseName;
int years;
System.out.println("Enter employee number you wish to remove");
number = scan.nextLine();
System.out.println("Input employee name");
name = scan.nextLine();
System.out.println("Input years at organisation");
years = scan.nextInt(); scan.nextLine();
System.out.println("Input course name");
courseName = scan.nextLine();
b = new employee(number,name,years,courseName);
list.clear(b);
}
}
public static void main(String[]args) {
new TrainingCourses();
}
}
I don't understand exactly what you want, because of you wrote you want "to remove all people from the list who have the same course name", but your code never checks only property, your code checks equality everywhere.
This example clear function removes all elements equals to param and returns count of removed elements.
public long clear(T element) {
long result = 0L;
LinearNode<T> current = this.list;
LinearNode<T> previous = null;
while (current != null) {
if (current.getElement().equals(element)) {
if (previous != null) {
if (current.getNext() != null) {
previous.setNext(current.getNext());
} else {
this.last = previous;
}
} else if (current.getNext() != null) {
this.list = current.getNext();
} else {
this.list = this.last = null;
}
this.count--;
result++;
} else {
previous = current;
}
current = current.getNext();
}
return result;
}
And after all .equals(..) only true, if the compared Objects has an equals() method and checks its content equality, otherwise two Objects equals by == operator, if they are exactly the same (not by there's contents).

Java: Converting a single-linked list into a doubly linked list from scratch

This is for a class assignment; I currently have a single-linked list and need to convert it into a doubly-linked list. Currently, the list is a collection of historical battles.
What in this program needs to be changed to turn this into a double-linked list? I feel like I'm really close, but stuck on a certain part (What needs to be changed in the 'add' part)
public static MyHistoryList HistoryList;
public static void main(String[] args) {
//Proof of concept
HistoryList = new MyHistoryList();
HistoryList.add("Battle of Vienna");
HistoryList.add("Spanish Armada");
HistoryList.add("Poltava");
HistoryList.add("Hastings");
HistoryList.add("Waterloo");
System.out.println("List to begin with: " + HistoryList);
HistoryList.insert("Siege of Constantinople", 0);
HistoryList.insert("Manzikert", 1);
System.out.println("List following the insertion of new elements: " + HistoryList);
HistoryList.remove(1);
HistoryList.remove(2);
HistoryList.remove(3);
System.out.println("List after deleting three things " + HistoryList);
}
}
class MyHistoryList {
//setting up a few variables that will be needed
private static int counter;
private Node head;
This is the private class for the node, including some getters and setters. I've already set up 'previous', which is supposed to be used in the implementation of the doubly-linked list according to what I've already googled, but I'm not sure how to move forward with the way MY single-list is set up.
private class Node {
Node next;
Node previous;
Object data;
public Node(Object dataValue) {
next = null;
previous = null;
data = dataValue;
}
public Node(Object dataValue, Node nextValue, Node previousValue) {
previous = previousValue;
next = nextValue;
data = dataValue;
}
public Object getData() {
return data;
}
public void setData(Object dataValue) {
data = dataValue;
}
public Node getprevious() {
return previous;
}
public void setprevious(Node previousValue) {
previous = previousValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
This adds elements to the list. I think I need to change this part in order to make this into a doubly-linked list, but don't quite understand how?
public MyHistoryList() {
}
// puts element at end of list
public void add(Object data) {
// just getting the node ready
if (head == null) {
head = new Node(data);
}
Node Temp = new Node(data);
Node Current = head;
if (Current != null) {
while (Current.getNext() != null) {
Current = Current.getNext();
}
Current.setNext(Temp);
}
// keeping track of number of elements
incrementCounter();
}
private static int getCounter() {
return counter;
}
private static void incrementCounter() {
counter++;
}
private void decrementCounter() {
counter--;
}
This is just tostring, insertion, deletion, and a few other things. I don't believe anything here needs to be changed to make it a doubly linked list?
public void insert(Object data, int index) {
Node Temp = new Node(data);
Node Current = head;
if (Current != null) {
for (int i = 0; i < index && Current.getNext() != null; i++) {
Current = Current.getNext();
}
}
Temp.setNext(Current.getNext());
Current.setNext(Temp);
incrementCounter();
}
//sees the number of elements
public Object get(int index)
{
if (index < 0)
return null;
Node Current = null;
if (head != null) {
Current = head.getNext();
for (int i = 0; i < index; i++) {
if (Current.getNext() == null)
return null;
Current = Current.getNext();
}
return Current.getData();
}
return Current;
}
// removal
public boolean remove(int index) {
if (index < 1 || index > size())
return false;
Node Current = head;
if (head != null) {
for (int i = 0; i < index; i++) {
if (Current.getNext() == null)
return false;
Current = Current.getNext();
}
Current.setNext(Current.getNext().getNext());
decrementCounter();
return true;
}
return false;
}
public int size() {
return getCounter();
}
public String toString() {
String output = "";
if (head != null) {
Node Current = head.getNext();
while (Current != null) {
output += "[" + Current.getData().toString() + "]";
Current = Current.getNext();
}
}
return output;
}
}

Java: How to implement Dancing Links algorithm (with DoublyLinkedLists)?

I am trying to implement Knuth's Dancing Links algorithm in Java.
According to Knuth, if x is a node, I can totally unlink a node by the following operations in C:
L[R[x]]<-L[x]
R[L[x]]<-R[x]
And revert the unlinking by:
L[R[x]]<-x
R[L[x]]<-x
What am I doing wrongly in my main method?
How do you implement the unlinking and revert in Java?
Here's my main method:
///////////////
DoublyLinkedList newList = new DoublyLinkedList();
for (int i = 0; i < 81; i++) {
HashSet<Integer> set = new HashSet<Integer>();
set.add(i);
newList.addFirst(set);
}
newList.displayList();
// start at 69
newList.getAt(12).displayNode();
//HOW TO IMPLEMENT UNLINK?
//newList.getAt(12).previous() = newList.getAt(12).next().previous().previous();
//newList.getAt(12).next() = newList.getAt(12).previous().next().next();
newList.displayList();
//HOW TO IMPLEMENT REVERT UNLINK?
//newList.getAt(12) = newList.getAt(12).next().previous();
//newList.getAt(12) = newList.getAt(12).previous().next();
System.out.println();
///////////////
Here's the DoublyLinkedList class:
public class DoublyLinkedList<T> {
public Node<T> first = null;
public Node<T> last = null;
static class Node<T> {
private T data;
private Node<T> next;
private Node<T> prev;
public Node(T data) {
this.data = data;
}
public Node<T> get() {
return this;
}
public Node<T> set(Node<T> node) {
return node;
}
public Node<T> next() {
return next;
}
public Node<T> previous() {
return prev;
}
public void displayNode() {
System.out.print(data + " ");
}
#Override
public String toString() {
return data.toString();
}
}
public void addFirst(T data) {
Node<T> newNode = new Node<T>(data);
if (isEmpty()) {
newNode.next = null;
newNode.prev = null;
first = newNode;
last = newNode;
} else {
first.prev = newNode;
newNode.next = first;
newNode.prev = null;
first = newNode;
}
}
public Node<T> getAt(int index) {
Node<T> current = first;
int i = 1;
while (i < index) {
current = current.next;
i++;
}
return current;
}
public boolean isEmpty() {
return (first == null);
}
public void displayList() {
Node<T> current = first;
while (current != null) {
current.displayNode();
current = current.next;
}
System.out.println();
}
public void removeFirst() {
if (!isEmpty()) {
Node<T> temp = first;
if (first.next == null) {
first = null;
last = null;
} else {
first = first.next;
first.prev = null;
}
System.out.println(temp.toString() + " is popped from the list");
}
}
public void removeLast() {
Node<T> temp = last;
if (!isEmpty()) {
if (first.next == null) {
first = null;
last = null;
} else {
last = last.prev;
last.next = null;
}
}
System.out.println(temp.toString() + " is popped from the list");
}
}
I am not familiar with Knuth's Dancing Links algorithm, but found this article which made it quiet clear. In particular I found this very helpful:
Knuth takes advantage of a basic principle of doubly-linked lists.
When removing an object from a list, only two operations are needed:
x.getRight().setLeft( x.getLeft() )
x.getLeft().setRight(> x.getRight() )
However, when putting the object back in the list, all
is needed is to do the reverse of the operation.
x.getRight().setLeft( x )
x.getLeft().setRight( x )
All that is
needed to put the object back is the object itself, because the object
still points to elements within the list. Unless x’s pointers are
changed, this operation is very simple.
To implement it I added setters for linking / unlinking. See comments:
import java.util.HashSet;
public class DoublyLinkedList<T> {
public Node<T> first = null;
public Node<T> last = null;
static class Node<T> {
private T data;
private Node<T> next;
private Node<T> prev;
public Node(T data) {
this.data = data;
}
public Node<T> get() {
return this;
}
public Node<T> set(Node<T> node) {
return node;
}
public Node<T> next() {
return next;
}
//add a setter
public void setNext(Node<T> node) {
next = node;
}
public Node<T> previous() {
return prev;
}
//add a setter
public void setPrevious(Node<T> node) {
prev = node;
}
public void displayNode() {
System.out.print(data + " ");
}
#Override
public String toString() {
return data.toString();
}
}
public void addFirst(T data) {
Node<T> newNode = new Node<T>(data);
if (isEmpty()) {
newNode.next = null;
newNode.prev = null;
first = newNode;
last = newNode;
} else {
first.prev = newNode;
newNode.next = first;
newNode.prev = null;
first = newNode;
}
}
public Node<T> getAt(int index) {
Node<T> current = first;
int i = 1;
while (i < index) {
current = current.next;
i++;
}
return current;
}
public boolean isEmpty() {
return (first == null);
}
public void displayList() {
Node<T> current = first;
while (current != null) {
current.displayNode();
current = current.next;
}
System.out.println();
}
public void removeFirst() {
if (!isEmpty()) {
Node<T> temp = first;
if (first.next == null) {
first = null;
last = null;
} else {
first = first.next;
first.prev = null;
}
System.out.println(temp.toString() + " is popped from the list");
}
}
public void removeLast() {
Node<T> temp = last;
if (!isEmpty()) {
if (first.next == null) {
first = null;
last = null;
} else {
last = last.prev;
last.next = null;
}
}
System.out.println(temp.toString() + " is popped from the list");
}
public static void main(String[] args) {
///////////////
DoublyLinkedList newList = new DoublyLinkedList();
for (int i = 0; i < 81; i++) {
HashSet<Integer> set = new HashSet<Integer>();
set.add(i);
newList.addFirst(set);
}
newList.displayList();
// start at 69
Node node = newList.getAt(12);
node.displayNode(); System.out.println();
//HOW TO IMPLEMENT UNLINK?
node.previous().setNext(node.next);
node.next().setPrevious(node.previous());
//The 2 statements above are equivalent to
//Node p = node.previous();
//Node n = node.next();
//p.setNext(n);
//n.setPrevious(p);
newList.displayList();
//HOW TO IMPLEMENT REVERT UNLINK?
node.previous().setNext(node);
node.next().setPrevious(node);
newList.displayList(); System.out.println();
///////////////
}
}

LinkedList - delete(Object) method works strange - deleting last element doesn't work properly

I have LinkedList with test program. As you can see in that program I add some Students to the list. I can delete them. If I choose s1,s2,s3 oraz s4 to delete everything runs well, and my list is printed properly and information about number of elements is proper. But if I delete last element (in this situation - s5) info about number of elements is still correct, but this element is still printed. Why is that so? Where is my mistake?
public class Lista implements List {
private Element head = new Element(null); //wartownik
private int size;
public Lista(){
clear();
}
public void clear(){
head.setNext(null);
size=0;
}
public void add(Object value){
if (head.getNext()==null) head.setNext(new Element(value));
else {
Element last = head.getNext();
//wyszukiwanie ostatniego elementu
while(last.getNext() != null)
last=last.getNext();
// i ustawianie jego referencji next na nowowstawiany Element
last.setNext(new Element(value));}
++size;
}
public Object get(int index) throws IndexOutOfBoundsException{
if(index<0 || index>size) throw new IndexOutOfBoundsException();
Element particular = head.getNext();
for(int i=0; i <= index; i++)
particular = particular.getNext();
return particular.getValue();
}
public boolean delete(Object o){
if(head.getNext() == null) return false;
if(head.getNext().getValue().equals(o)){
head.setNext(head.getNext().getNext());
size--;
return true;
}
Element delete = head.getNext();
while(delete != null && delete.getNext() != null){
if(delete.getNext().getValue().equals(o)){
delete.setNext(delete.getNext().getNext());
size--;
return true;
}
delete = delete.getNext();
}
return false;
}
public int size(){
return size;
}
public boolean isEmpty(){
return size == 0;
}
public IteratorListowy iterator() {
return new IteratorListowy();
}
public void wyswietlListe() {
IteratorListowy iterator = iterator();
for (iterator.first(); !iterator.isDone(); iterator.next())
{
System.out.println(iterator.current());
}
System.out.println();
}
public void infoOStanie() {
if (isEmpty()) {
System.out.println("Lista pusta.");
}
else
{
System.out.println("Lista zawiera " + size() + " elementow.");
}
}
private static final class Element{
private Object value;
private Element next; //Referencja do kolejnego obiektu
public Element(Object value){
setValue(value);
}
public void setValue(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
//ustawia referencję this.next na obiekt next podany w atgumencie
public void setNext(Element next) {
if (next != null)
this.next = next;
}
public Element getNext(){
return next;
}
}
private class IteratorListowy implements Iterator{
private Element current;
public IteratorListowy() {
current = head;
}
public void next() {
current = current.next;
}
public boolean isDone() {
return current == null;
}
public Object current() {
return current.value;
}
public void first() {
current = head.getNext();
}
}
}
test
public class Program {
public static void main(String[] args) {
Lista lista = new Lista();
Iterator iterator = lista.iterator();
Student s1 = new Student("Kowalski", 3523);
Student s2 = new Student("Polański", 45612);
Student s3 = new Student("Karzeł", 8795);
Student s4 = new Student("Pałka", 3218);
Student s5 = new Student("Konowałek", 8432);
Student s6 = new Student("Kłopotek", 6743);
Student s7 = new Student("Ciołek", 14124);
lista.add(s1);
lista.add(s2);
lista.add(s3);
lista.add(s4);
lista.add(s5);
lista.wyswietlListe();
lista.delete(s5);
lista.wyswietlListe();
lista.infoOStanie();
lista.clear();
lista.infoOStanie();
}
}
The problem is that your setNext(Element next) method does not set anything if next == null. And that is the case for the last element of your list.
So when you call delete.setNext(delete.getNext().getNext());, nothing is actually set because delete.getNext().getNext() is null!
Remove the if (next != null) condition in setNext and it will work.

Class Cast Error trying to use compareTo with node and elements in a linked list

I've looked at a bunch of the questions in this area and can't find one that solves my problem specifically.
Basically, this is a homework assigment where I have a linked list with nodes, which hold an element. The node class (LinearNode) and the element class (Golfer) both implement Comparable and override the compareTo method. However, the runtime fails trying to add a new node to the list (first node is added fine) with a class cast exception: supersenior.LinearNode cannot be cast to supersenior.Golfer. I don't know why it's trying to take the node and compare it to an element of the node to be compared...i've even tried explicitly casting. The following error is observed:
Exception in thread "main" java.lang.ClassCastException: supersenior.LinearNode cannot be cast to supersenior.Golfer
at supersenior.Golfer.compareTo(Golfer.java:12)
at supersenior.LinearNode.compareTo(LinearNode.java:80)
at supersenior.LinearNode.compareTo(LinearNode.java:80)
at supersenior.LinkedList.add(LinkedList.java:254)
at supersenior.SuperSenior.main(SuperSenior.java:100)
Any help would be greatly appreciated. Thanks!
LinkedList class:
package supersenior;
import supersenior.exceptions.*;
import java.util.*;
public class LinkedList<T> implements OrderedListADT<T>, Iterable<T>
{
protected int count;
protected LinearNode<T> head, tail;
/**
* Creates an empty list.
*/
public LinkedList()
{
count = 0;
head = tail = null;
}
public T removeFirst() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException ("List");
LinearNode<T> result = head;
head = head.getNext();
if (head == null)
tail = null;
count--;
return result.getElement();
}
public T removeLast() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException ("List");
LinearNode<T> previous = null;
LinearNode<T> current = head;
while (current.getNext() != null)
{
previous = current;
current = current.getNext();
}
LinearNode<T> result = tail;
tail = previous;
if (tail == null)
head = null;
else
tail.setNext(null);
count--;
return result.getElement();
}
public T remove (T targetElement) throws EmptyCollectionException,
ElementNotFoundException
{
if (isEmpty())
throw new EmptyCollectionException ("List");
boolean found = false;
LinearNode<T> previous = null;
LinearNode<T> current = head;
while (current != null && !found)
if (targetElement.equals (current.getElement()))
found = true;
else
{
previous = current;
current = current.getNext();
}
if (!found)
throw new ElementNotFoundException ("List");
if (size() == 1)
head = tail = null;
else if (current.equals (head))
head = current.getNext();
else if (current.equals (tail))
{
tail = previous;
tail.setNext(null);
}
else
previous.setNext(current.getNext());
count--;
return current.getElement();
}
public boolean contains (T targetElement) throws
EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException ("List");
boolean found = false;
Object result;
LinearNode<T> current = head;
while (current != null && !found)
if (targetElement.equals (current.getElement()))
found = true;
else
current = current.getNext();
return found;
}
public boolean isEmpty()
{
return (count == 0);
}
public int size()
{
return count;
}
public String toString()
{
LinearNode<T> current = head;
String result = "";
while (current != null)
{
result = result + (current.getElement()).toString() + "\n";
current = current.getNext();
}
return result;
}
public Iterator<T> iterator()
{
return new LinkedIterator<T>(head, count);
}
public T first()
{
return head.getElement();
}
public T last()
{
return tail.getElement();
}
#Override
public void add (T element)
{
LinearNode<T>node = new LinearNode<T>();
node.setElement(element);
if(isEmpty())
{
head = node;
if(tail == null)
tail = head;
//node.setNext(head);
//head.setPrevious(node);
//head.setElement((T) node);
count++;
}
else
{
for(LinearNode<T> current = head; current.getNext() != null; current = current.getNext())
if(node.compareTo((T) current) >= 0)
{
current.setPrevious(current);
current.setNext(current);
}
else
{
current.setPrevious(node);
}
tail.setNext(node);
}
}
}
LinearNode class:
package supersenior;
public class LinearNode<E> implements Comparable<E>
{
private LinearNode<E> next, previous;
public E element;
public LinearNode()
{
next = null;
element = null;
}
public LinearNode (E elem)
{
next = null;
element = elem;
}
public LinearNode<E> getNext()
{
return next;
}
public void setNext (LinearNode<E> node)
{
next = node;
}
public E getElement()
{
return element;
}
public void setElement (E elem)
{
element = elem;
}
#Override
public int compareTo(E otherElement) {
return ((Comparable<E>) this.element).compareTo(otherElement);
}
public LinearNode<E> getPrevious()
{
return previous;
}
public void setPrevious (LinearNode<E> node)
{
previous = node;
}
}
The element class (Golfer):
package supersenior;
public class Golfer implements Comparable<Golfer>{
Golfer imaGolfer;
String name;
int tourneys;
int winnings;
double avg;
public Golfer(String attr[]){
this.name = attr[0];
this.tourneys = Integer.parseInt(attr[1]);
this.winnings = Integer.parseInt(attr[2]);
this.avg = findAvg(winnings, tourneys);
}
private double findAvg(int winnings, int tourneys){
double a = winnings/tourneys;
return a;
}
#Override
public String toString(){
return "Name: " + name + " Tourneys: " + tourneys + " Winnings: " + winnings + " Average: " + avg;
}
#Override
public int compareTo(Golfer golfer) {
if(this.avg <= golfer.avg)
return 1;
if(this.avg == golfer.avg)
return 0;
else
return -1;
}
}
The problem is that you're mixing what's being compared. You're trying to compare the LinearNode object (which holds an E) to an actual E. LinearNode<E> shouldn't implement Comparable<E>; if anything, it might implement Comparable<LinearNode<E>>, and the type parameter should probably be E extends Comparable<E>.
If you want to order LinearNodes based on the ordering of their underlying elements, you should use something like this:
// in LinearNode
public int compareTo(LinearNode<E> otherNode) {
return this.element.compareTo(otherNode.element);
}
(Note that the Java sorted collections don't require elements to implement Comparable, since you can provide a custom Comparator for any of them, but in the case of this assignment it's probably fine to require that E extends Comparable<E>.)
(Note 2: If you're using Generics, any cast, such as your (Comparable<E>), is a red flag; the purpose of the Generics system is to eliminate the need for most explicit casts.)

Categories

Resources