Sorting a List alphabetically using compareTo() method - java

I am writing a phonebook program in java and i need to list people in the list alphabetically and to do that i need to write a sorting algorithm for a list in java and it should use only compareTo() method. So can anyone help me to do that?
public void listAlpha()
{
Node tempNode = head;
for(int i = 0; i <= size; i++)
{
for(int j = 0; j <= i; j++)
{
int comparison = ((tempNode.getNext().getElement().getName()).compareTo(tempNode.getElement().getName()));
if(comparison < 0)
{
Person tempPerson = tempNode.getElement();
tempNode.setElement(tempNode.getNext().getElement());
tempNode.getNext().setElement(tempPerson);
tempNode = tempNode.getNext();
}
}
}
(By the way this is a homework and i am using my own data structures.)
This is the class that method i wrote above belongs:
import java.util.*;
/** Singly linked list implementation .*/
public class SLinkedList<E> implements LinkedList<E>, Iterable<E> {
protected Node<E> head; // head node of the list
protected Node<E> tail; // tail node of the list
protected int size; // number of nodes in the list
public Iterator<E> iterator()
{
return new LinkedListIterator(head);
}
/** Default constructor that creates an empty list */
public SLinkedList() {
head = null;
tail = null;
size = 0;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public void addFirst(E newElement) {
Node<E> newNode = new Node(newElement,null);
if(size == 0) //if list is empty
tail = newNode;
newNode.setNext(head);
head = newNode;
size++;
}
public void addLast(E newElement) {
Node<E> newNode = new Node(newElement,null);
if(size == 0) //if list is empty
head = newNode;
if (size != 0) //if list is not empty
tail.setNext(newNode);
tail = newNode;
size++;
}
public E removeFirst() {
Node<E> tempNode = null;
if (size != 0) {
if(size == 1)
tail = null;
tempNode = head;
head = head.getNext();
tempNode.setNext(null);
size--;
}
//if list is empty then return null
return tempNode.getElement();
}
public E removeLast() {
Node<E> tempNode = head;
if(size == 0)
return null;
if(size == 1) {
head = null;
tail = null;
size--;
return tempNode.getElement();
}
//size is greater than 1
for(int i=1; i<=size-2; i++) {
tempNode = tempNode.getNext(); //go to element that before the tail
}
Node<E> tempNode2 = tail;
tail = tempNode;
tail.setNext(null);
size--;
return tempNode2.getElement();
}
public void remove(E element){
int index = 0;
boolean found = false;
Node<E> temp = head;
for(int i=1; i<=size; i++) {//find the node with element
index++;
if(temp.getElement().equals(element)){
found = true;
break;
}
temp = temp.getNext();
}
if(found){
if(index == 1)
removeFirst();
else if(index == size)
removeLast();
else{
//find the previous node
Node<E> prev = head;
for(int i=1; i<index-1; i++) {
prev = prev.getNext();
}
prev.setNext(temp.getNext());
temp.setNext(null);
size--;
}
}
}
public int searchList(E searchKey) {
if(size == 0)
return -1;
Node tempNode = head;
for(int i=1; i<=size; i++) {
if(tempNode.getElement().equals(searchKey))
return i; //return index of the node
tempNode = tempNode.getNext();
}
return -1; //not found
}
public void printList() {
Node tempNode = head;
for(int i=1; i<=size; i++) {
System.out.print(tempNode.getElement());
if(i!=size) //if it is not last element
System.out.print(" - ");
tempNode = tempNode.getNext();
}
System.out.println();
}
Person class:
public class Person
{
private String name;
private String surname;
private String address;
private PhoneNumber phone1;
private PhoneNumber phone2;
private PhoneNumber phone3;
public Person()
{
name = null;
surname = null;
address = null;
phone1.setPhone(0);
phone1.setType("");
phone2.setPhone(0);
phone2.setType("");
phone3.setPhone(0);
phone3.setType("");
}
public Person(String n, String s, String a,PhoneNumber p1, PhoneNumber p2, PhoneNumber p3)
{
name = n;
surname = s;
address = a;
phone1 = p1;
phone2 = p2;
phone3 = p3;
}
public String getName()
{
return name;
}
public void setName(String n)
{
name = n;
}
public String getSur()
{
return surname;
}
public void setSur(String s)
{
surname = s;
}
public void insertPhone(PhoneNumber phone)
{
if(phone2 == null)
phone2 = phone;
else if(phone3 == null)
phone3 = phone;
}
public PhoneNumber getPhone1()
{
return phone1;
}
public PhoneNumber getPhone2()
{
return phone2;
}
public PhoneNumber getPhone3()
{
return phone3;
}
public String getAdd()
{
return address;
}
public void setAdd(String a)
{
address = a;
}

You can make your Person class implement Comparable, and define the following method:
public class Person implements Comparable<Person> {
// Your previous code
public int compareTo(Person other) {
if (other == null) {
// throw exception for example
}
return this.name.toLowerCase().compareTo(other.name.toLowerCase());
}
}

As everyone else has mentioned, compareTo is part of the Comparable interface.
How you implement it depends on whether you want to order by surname or name first and if you want them sorted ascending order.
For example, if you want to order by surname first, in ascending order:
public class Person implements Comparable<Person> {
// the parts of Person you already have would go here
public int compareTo(Person person) {
if (person == null) {
return -1;
}
if (surname != null && person.getSur() == null) {
return -1;
} else if (surname == null && person.getSur() != null) {
return 1;
} else if (surname != null && person.getSur() != null) {
int compare = surname.compareToIgnoreCase(person.getSur());
if (compare != 0) {
return compare;
}
}
// Note that we did nothing if both surnames were null or equal
if (name == null && person.getName() == null) {
return 0;
} else if (name != null && person.getName() == null) {
return -1;
} else if (name == null && person.getName() != null) {
return 1;
} else {
return name.compareToIgnoreCase(person.getName());
}
}
}
(I didn't actually test this code)
This relies on String's implementation of compareToIgnoreCase.
Note that this also moves all null objects and objects with null names and surnames to the end of the list.
Having said all that, if you implement Comparable, you can make the Collections API do the work for you using sort.
If you find that you need multiple different sort methods for an object, you can create a set of Comparator objects to do the sorting instead.

The Person class' signature should be like this:
public class Person implements Comparable<Person>
Add compareTo-method to Person class and use Collections.sort(personList) as starf suggested.

Implement Comparable in your Person class.
Your compareTo() method would then be something like:
public int compareTo(Person other) {
return name.compareTo(other.getName())
}
Then use Collections.sort(<your list of Person>);

Related

Is it possible to use 2 Data Type in an Custom ADT(Sorted Linked List)?

I am trying to do a Leaderboard for a game by using a Sorted Linked List. I was able to do so by sorting the point in descending order which mean higher point to lower point. Moreover, I will also need to put player name together with the point. The problem comes here. The SLL(Sorted Linked List) I implemented is an Integer data type, it works perfectly with the Integer data type as it sorted the numbers.
SortedListInterface<Integer> Player = new LeaderboardSortedLinkedList<Integer>();
But when I trying to put the player name which used String, it won't be able to do so because the point data type will need to follow the player name's data type.
Below are the codes of the driver class:
public class testLeaderboard {
public static void main(String[] args) {
SortedListInterface<Integer> Player = new LeaderboardSortedLinkedList<Integer>();
Player.add(1000000);
Player.add(500000);
Player.add(250000);
Player.add(125000);
Player.add(64000);
Player.add(32000);
Player.add(16000);
Player.add(8000);
Player.add(4000);
Player.add(2000);
Player.add(1000);
Player.add(500);
Player.add(300);
Player.add(200);
Player.add(100);
System.out.printf("=================================\n"
+ " Leaderboard\n"
+"=================================\n");
for(int i=0; i< Player.size();i++){
System.out.printf("%3d. %s\n",(i+1), Player.get(i+1));
}
}
}
Here is the Entity class
public class Player {
private String name;
private int prize;
public Player(String name, int prize) {
this.name = name;
this.prize = prize;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrize() {
return prize;
}
public void setPrize(int prize) {
this.prize = prize;
}
#Override
public String toString() {
return "Player{" + "name=" + name + ", prize=" + prize + '}';
}
}
Here's the custom Sorted Lineked List
public class LeaderboardSortedLinkedList<T extends Comparable<T>> implements SortedListInterface<T> {
private Node firstNode;
private int length;
public LeaderboardSortedLinkedList() {
firstNode = null;
length = 0;
}
public boolean add(T newEntry) {
Node newNode = new Node(newEntry);
Node nodeBefore = null;
Node currentNode = firstNode;
while (currentNode != null && newEntry.compareTo(currentNode.data) < 0) {
nodeBefore = currentNode;
currentNode = currentNode.next;
}
if (isEmpty() || (nodeBefore == null)) { // CASE 1: add at beginning
newNode.next = firstNode;
firstNode = newNode;
} else { // CASE 2: add in the middle or at the end, i.e. after nodeBefore
newNode.next = currentNode;
nodeBefore.next = newNode;
}
length++;
return true;
}
public boolean contains(T anEntry) {
boolean found = false;
Node tempNode = firstNode;
int pos = 1;
while (!found && (tempNode != null)) {
if (anEntry.compareTo(tempNode.data) <= 0) {
found = true;
} else {
tempNode = tempNode.next;
pos++;
}
}
if (tempNode != null && tempNode.data.equals(anEntry)) {
return true;
} else {
return false;
}
}
public int size(){
int count = 0;
//Node current will point to head
Node current = firstNode;
while(current != null) {
//Increment the count by 1 for each node
count++;
current = current.next;
}
return count;
}
public T get(int position){
T result = null;
if ((position >= 1) && (position <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < position - 1; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}
public final void clear() {
firstNode = null;
length = 0;
}
public int getLength() {
return length;
}
public boolean isEmpty() {
return (length == 0);
}
public String toString() {
String outputStr = "";
Node currentNode = firstNode;
while (currentNode != null) {
outputStr += currentNode.data + "\n";;
currentNode = currentNode.next;
}
return outputStr;
}
private class Node {
private T data;
private Node next;
private Node(T data) {
this.data = data;
next = null;
}
private Node(T data, Node next) {
this.data = data;
this.next = next;
}
}
}
And the results is here
=================================
Leaderboard
=================================
1. 1000000
2. 500000
3. 250000
4. 125000
5. 64000
6. 32000
7. 16000
8. 8000
9. 4000
10. 2000
11. 1000
12. 500
13. 300
14. 200
15. 100
Here's my testing on the point with string data type because I can't think a way to use player name and point with 2 different data types at the same time in my custom ADT.
public class testLeaderboard {
public static void main(String[] args) {
SortedListInterface<String> Player = new LeaderboardSortedLinkedList<String>()
Player.add("1000000");
Player.add("500000");
Player.add("250000");
Player.add("125000");
Player.add("64000");
Player.add("32000");
Player.add("16000");
Player.add("8000");
Player.add("4000");
Player.add("2000");
Player.add("1000");
Player.add("500");
Player.add("300");
Player.add("200");
Player.add("100");
System.out.println(Player);
}
And here's the result that it compare the first letter of the string.
8000
64000
500000
500
4000
32000
300
250000
2000
200
16000
125000
1000000
1000
100
Is there anyway to use both String and Integer in one ADT because if i couldn't do so, I won't be able sort the point. I'm so sorry for the long question. I am very new to data structures and algorithms so I really need some help on this. Much appreciate.
To keep the points and names together, you need to add Player objects into the list as they are, not just their points or their names:
SortedListInterface<Player> players = new LeaderboardSortedLinkedList<>();
players.add(new Player("Alpha", 1000000));
players.add(new Player("Beta", 500000));
players.add(new Player("Gamma", 250000));
For this to work, you will need to be able to compare Player objects by their point numbers. You do that by implementing the Comparable interface and adding a compareTo method.
You'll also want to add a toString() method, so that you can print a Player object.
public class Player implements Comparable<Player> {
private String name;
private int prize;
#Override
public int compareTo(Player other) {
return Integer.compare(this.prize, other.prize);
}
#Override
public String toString() {
return String.format("name='%s' prize=%d", name, prize);
}
}
Thank You for helping me I successfully get the output I want. But got a little problem which is this
=================================
Leaderboard
=================================
1. name='Alpha' prize=1000000
2. name='Beta' prize=500000
3. name='Gamma' prize=250000
BUILD SUCCESSFUL (total time: 1 second)
It print the output at this way [name="Alpha"]. Im not sure what is the problem but i guess it's my System.out.print code.
System.out.printf("%3d. %s\n",(i+1), players.get(i+1));
and here's my .get() function.
public T get(int position){
T result = null;
if ((position >= 1) && (position <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < position - 1; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}

Deleting a node at a given index in Java; What am I doing wrong?

I have been stuck for the last 40-so minutes on this problem. I'm unsure of what I am doing wrong here, I have tried debugging many times and have read similar Q/A's. Can't figure it out and my assignment is due at midnight.
It is not deleting the Node.. None at all in fact. If the code seems right, then the problem may be lying inside main. Let me know, please & thank you!
Any help is well appreciated! :)
Problem Method Below
void deleteAtIndex(int idx)
{
if (length() >= idx)
{
if(idx == 0)
{
head = head.getNext();
}
else
{
Node temp = findAtIndex(idx-1);
temp.setNext(temp.getNext().getNext());
}
}
else
System.out.println("Invalid position");
}
Full Class Code Below
public class ShapeLinkedList {
public Node head; // Head is first node in linked list
public ShapeLinkedList() { }
public ShapeLinkedList(Node head) {
}
public boolean isEmpty() {
return length() == 0;
}
public void insertAtEnd(Shape data) {
Node end = new Node(data, null);
if (head == null)
head.setNext(end);
else
tail().setNext(end);
}
public void insertAtBeginning(Shape data) {
if (data != null)
{
Node temp = new Node(data, head);
head = temp;
}
}
public Node tail() {
if (head == null){
return null;
}
else
{
Node temp = head;
while(temp.getNext() != null){
temp = temp.getNext();
}
return temp;
}
}
public int length() { // 1
Node temp = head;
if (temp == null)
return 0;
int tempIndex = 0;
while(temp.getNext() != null){
temp = temp.getNext();
tempIndex++;
}
return tempIndex;
}
void insertAtIndex(int idx, Shape data) { //3
if (length() >= idx)
{
Node current = new Node(data, null);
Node temp = findAtIndex(idx);
current.setNext(temp.getNext());
temp.setNext(current);
}
}
Node findAtIndex(int idx) { // 2
if (length() >= idx)
{
Node temp = head;
for(int i = 0; i < idx; i++)
{
temp = temp.getNext();
}
return temp;
}
else
return null;
}
void deleteAtIndex(int idx) { //4
if (length() >= idx)
{
if(idx == 0)
{
head = head.getNext();
}
else
{
Node temp = findAtIndex(idx-1);
temp.setNext(temp.getNext().getNext());
}
}
else
System.out.println("Invalid position");
}
#Override
public String toString() {
return "";
}
void deleteData(Shape s) {
Node temp = head;
for(int i = 0; i < length(); i++)
{
if(temp.getData() == s)
deleteAtIndex(i);
}
}
#Override
public int hashCode() {
return 0;
}
#Override
public boolean equals(Object obj) {
return false;
}
// Node is nested class because it only exists along with linked list
public static class Node {
private Shape data;
private Node next;
public Node(Shape S, Node N){
data = S;
next = N;
}
public Node getNext(){
return next;
}
public Shape getData() { return data; }
public void setNext(Node N) { next = N; }
// TODO develop all the methods that are needed
// such as constructors, setters, getters
// toString, equals, hashCode
}
}
You have multiple bugs in your class. I guess if you fix them, your code will work fine. SO is not a debugging platform, thus your question is off-topic and you should learn using a debugger.
Here some issues I instantly have seen from a quick look at your code, I'm sure there are more issues:
if (length() >= idx) should probably be if (length() > idx) at all places and
if (head == null) head.setNext(end); should probably be if (head == null) head = end; and
public ShapeLinkedList(Node head) { } should probably be public ShapeLinkedList(Node head) { this.head = head; } and
int tempIndex = 0 should probably be int tempIndex = 1

Sorting a generic LinkedList

I have to sort through a LinkedList, but i can't figure out why it only sorts it once and then stops. I am having a hard time understanding generic types and how to use them. Most of the examples i found were about sorting integer arrays, but i still couldn't translate those examples into my sort method. Anything that could help me understand how to sort this would be greatly appreciated.
public void sort() {
Node<T> current = head;
while(current != null){
if(current.getNext()!=null && current.getItem().compareTo(current.getNext().getItem()) < 0){
T temp = current.getItem();
current.setItem(current.getNext().getItem());
current.getNext().setItem(temp);
}
current = current.getNext();
}
current = head;
}
Here is my LinkedList class
public class LinkedList<T extends Comparable<T>> implements LinkedList161<T> {
protected Node<T> head;
protected int size;
public LinkedList() {
head = null;
size = 0;
}
public void add(T item, int index) {
if(index < 0 || index > size){
throw new IndexOutOfBoundsException("out of bounds");
}
if(index == 0){
head = new Node<T>(item, head);
}
else{
Node<T> current = head;
for(int i = 0; i < index -1; i ++){
current = current.getNext();
}
current.setNext(new Node<T>(item, current.getNext()));
}
size++;
}
public void addFirst(T item) {
head = new Node<T>(item, head);
size++;
}
public void addToFront(T item) {
head = new Node<T>(item, head);
size++;
}
public void addToBack(T item) {
if(head == null){
head = new Node<T>(item);
size++;
}
else{
Node<T> temp = head;
while(temp.getNext() != null){
temp = temp.getNext();
}
temp.setNext(new Node<T>(item));
size++;
}
}
public void remove(int index) {
if(index < 0 || index > size){
System.out.println("Index out of bounds");
}
if(index == 0){
head = head.getNext();
}else{
Node<T> current = head;
for(int i = 0; i < index;i++){
current = current.getNext();
}
current.setNext(current.getNext().getNext());
}
size--;
}
public T get(int index){
Node<T> p = head;
for(int i = 0; i < index;i++){
p = p.getNext();
}
return p.getItem();
}
public void clear() {
head = null;
size = 0;
}
public int size() {
return size;
}
#Override
public String toString() {
String result = "";
if (head == null)
return result;
for (Node<T> p = head; p != null; p = p.getNext()) {
result += p.getItem() + "\n";
}
return result.substring(0,result.length()-1); // remove last \n
}
#Override
public void sort() {
Node<T> current = head;
for(int i = 0; i < size;i++){
if(current.getNext()!=null && current.getItem().compareTo(current.getNext().getItem()) < 0){
T temp = current.getItem();
current.setItem(current.getNext().getItem());
current.getNext().setItem(temp);
}
current = current.getNext();
}
current = head;
}
}
Here is my Node class
public class Node<T> implements Node161<T>{
protected T item;
protected Node<T> next;
public Node(T item, Node<T> next) {
setItem(item);
setNext(next);
}
public Node(T item) {
setItem(item);
}
public T getItem() {
return item;
}
public void setItem(T i) {
item = i;
}
public void setNext(Node<T> n) {
next = n;
}
public Node<T> getNext() {
return next;
}
#Override
public String toString() {
return item.toString();
}
}
Your implementation of sort does just one step of sorting: it orders adjacent items and after this step things get better but the whole collection will not be sorted. You should repeat this step until your collection gets sorted.
Note that this algorithm is not efficient. You should look at some more sophisticated approach like merge sort
Wiki merge sort article now includes a simple but fast bottom up merge sort for linked lists that uses a small array (usually 26 to 32) of pointers to the first nodes of a list, where array[i] is either null or points to a list of size 2 to the power i. Unlike some other approaches, there's no scanning of lists, instead, the array is used along with a common merge function that merges two already sorted lists. Link to article:
http://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation_using_lists

Implementing Singly Linked List

I am trying to learn data structure, but I ran into the dreaded NullPointerException and I am not sure how to fix it.
My SinglyLinkedList<E> class implements an interface, LinkedList, where I redefined some methods like, add(), get(), contains(), and more.
The NullPointerException happens when I use the clear() method. It points at the method removeLast() under nodeBefore.setNext(null). It also points to the clear() method under remove(head.getElement()).
Also, if there is anything I can improve upon in my code please let me know.
public class SinglyLinkedList<E> implements LinkedList<E> {
private class Node<E> {
public Node<E> next;
public E element;
public Node(E element) {
this.element = element;
}
public Node (E element, Node<E> next) {
this.element = element;
this.next = next;
}
public E getElement() {
return element;
}
public Node<E> getNext() {
return next;
}
public void setElement(E element) {
this.element = element;
}
public void setNext(Node<E> next) {
this.next = next;
}
public String toString() {
return ("[" + element + "] ");
}
}
public Node<E> head;
public Node<E> tail;
public int total;
public SinglyLinkedList() {
this.head = null;
this.tail = null;
this.total = 0;
}
public E get(int index) {
if (index < 0 || index > size()) {
return null;
}
if (index == 0) {
return head.getElement();
}
Node<E> singly = head.getNext();
for (int i = 1; i < index; i ++) {
if (singly.getNext() == null) {
return null;
}
singly = singly.getNext();
}
System.out.println("\n" + singly.getElement());
return singly.getElement();
}
public void add(E element) {
Node<E> singlyAdd = new Node<E>(element);
if (tail == null) {
head = singlyAdd;
tail = singlyAdd;
} else {
tail.setNext(singlyAdd);
tail = singlyAdd;
}
total++;
}
public void display() {
if (head == null) {
System.out.println("empty list");
} else {
Node<E> current = head;
while (current != null) {
System.out.print(current.toString());
current = current.getNext();
}
}
}
public boolean contains(E data) {
if (head == null) {
return false;
}
if (head.getElement() == data) {
System.out.println(head);
return true;
}
while (head.getNext() != null) {
head = head.getNext();
if (head.getElement() == data) {
System.out.println(head);
return true;
}
}
return false;
}
private Node<E> removeFirst() {
if (head == null) {
System.out.println("We cant delete an empty list");
}
Node<E> singly = head;
head = head.getNext();
singly.setNext(null);
total--;
return singly;
}
private Node<E> removeLast() {
Node<E> nodeBefore;
Node<E> nodeToRemove;
if (size() == 0) {
System.out.println("Empty list");
}
nodeBefore = head;
for (int i = 0; i < size() - 2; i++) {
nodeBefore = nodeBefore.getNext();
}
nodeToRemove = tail;
nodeBefore.setNext(null);
tail = nodeBefore;
total--;
return nodeToRemove;
}
public E remove(int index) {
E hold = get(index);
if (index < 0 || index >= size()) {
return null;
} else if (index == 0) {
removeFirst();
return hold;
} else {
Node<E> current = head;
for (int i = 1; i < index; i++) {
current = current.getNext();
}
current.setNext(current.getNext().getNext());
total--;
return hold;
}
}
public int size() {
return getTotal();
}
public boolean remove(E data) {
Node<E> nodeBefore, currentNode;
if (size() == 0) {
System.out.println("Empty list");
}
currentNode = head;
if (currentNode.getElement() == data) {
removeFirst();
}
currentNode = tail;
if (currentNode.getElement() == data) {
removeLast();
}
if (size() - 2 > 0) {
nodeBefore = head;
currentNode = head.getNext();
for (int i = 0; i < size() - 2; i++) {
if (currentNode.getElement() == data) {
nodeBefore.setNext(currentNode.getNext());
total--;
break;
}
nodeBefore = currentNode;
currentNode = currentNode.getNext();
}
}
return true;
}
public void clear() {
while (head.getNext() != null) {
remove(head.getElement());
}
remove(head.getElement());
}
private int getTotal() {
return total;
}
}
For your clear method, I don't see that you do any per element cleanup, and the return type is void, so all you want is an empty list. The easiest way is to simply clear everything, like in the constructor:
public void clear() {
this.head = null;
this.tail = null;
this.total = 0;
}
Another comment:
in contains, you do
while (head.getNext() != null) {
head = head.getNext();
if (head.getElement() == data) {
System.out.println(head);
return true;
}
}
which may have two problems (where the first applies to the entire class),
you compare with == data which compares references, where you probably want to compare values with .equals(data)
Edit: I.e. n.getElement().equals(data) instead of n.getElement() == data.
(Or, if n and data may be null, something like (data != null ? data.equals(n.getElement()) : data == n.getElement())
you use the attribute head as the scan variable which modifies the state of the list. Do you really want that?
The problem arises when you delete the last element within clear: remove(head.getElement());. For some reason, you first remove the head and then the tail. But when calling removeLast, you use the head (which is already null). Within removeLast this is the line, which causes the NullPointerException: nodeBefore.setNext(null);.
My advice would be to write the clear() method as #bali182 has suggested:
public void clear() {
this.head = null;
this.tail = head;
this.total = 0;
}
One advice: if you are writing methods to search or delete entries, you should never use == when dealing with objects (or even better: don't use == at all when dealing with objects). You may want to read this thread.
From within clear method, you are calling remove(head.getElement()); meaning you are trying to call LinkedList's remove method. And since you are overriding each functionality and so is add, you don't maintain internal state of LinkedList and hence you get exception. Code in remove is:
public boolean remove(Object o) {
if (o==null) {
for (Entry<E> e = header.next; e != header; e = e.next) {
if (e.element==null) {
So here since you are not using functionality of LinkedList, header would be null and doing header.next would return NullPointerException.

Linked List Array

I have this school assignment that I'm a little confused about.
Here's what it's saying:
"Write a program that uses the technique of 'chaining' for hashing.
The program will read in the length of an array which will contain the reference to each
linked list that will be generated. Furthermore, all values that are to be stored, is read.
The program shall have a separate function for hashing where the index exists. When the program have generated the linked lists, the theoretical 'load factor' is to be calculated and printed out. The whole array should be easily printed out."
The thing that I'm confused about, is the part about the program will read in the length of an array which will contain the reference to each linked list that will be generated. Is it possible to generate multiple linked lists? In that case, how do you do that?
This is the classes I'm told to use:
public class EnkelLenke {
private Node head = null;
private int numOfElements = 0;
public int getNum()
{
return numOfElements;
}
public Node getHead()
{
return head;
}
public void insertInFront(double value)
{
head = new Node (value, head);
++numOfElements;
}
public void insertInBack(double value)
{
if (head != null)
{
Node this = head;
while (this.next != null)
this = this.next;
this.next = new Node(value, null);
}
else
head = new Node(value, null);
++numOfElements;
}
public Node remove(Node n)
{
Node last = null;
Node this = head;
while (this != null && this != n)
{
last = this;
this = this.next;
}
if (this != null)
{
if (last != null)
last.next = this.next;
else
head = this.next;
this.next = null;
--numOfElements;
return this;
}
else
return null;
}
public Node findNr(int nr)
{
Node this = head;
if (nr < numOfElements)
{
for (int i = 0; i < nr; i++)
this = this.next;
return this;
}
else
return null;
}
public void deleteAll()
{
head = null;
numOfElements = 0;
}
public String printAllElements() {
String streng = new String();
Node this = head;
int i = 1;
while(this != null)
{
streng = streng + this.element + " ";
this = this.findNext();
i++;
if(i > 5)
{
i = 1;
streng = streng + "\n";
}
}
return streng;
}
public double getValueWithGivenNode (Node n)
{
Node this = head;
while (this != null && this != n)
{
this = this.next;
}
if (this == n)
return this.element;
else
return (Double) null;
}
}
public class Node {
double element;
Node next;
public Node(double e, Node n)
{
element = e;
next = n;
}
public double findElement()
{
return element;
}
public Node findNext()
{
return next;
}
}
Your data structure will look something like this (where "LL" is a linked list):
i | a[i]
-------------------------------
0 | LL[obj1 -> obj5 -> obj3]
1 | LL[obj2]
2 | LL[]
... | ...
N-1 | LL[obj4 -> obj6]
At each array index, you have a linked list of objects which hash to that index.
Is it possible to generate multiple linked lists? In that case, how do you do that?
Yes. Create your array, and initialize each element to a new linked list.
EnkelLenke[] a = new EnkelLenke[N];
for ( int i = 0; i < N; i++ ) {
a[i] = new EnkelLenke();
}

Categories