compare objects in priority queue - java

I implemented a priority queue with linked list like this,when for first time I make an object from seller class and add it to priority queue, it works, but when I make second object from seller to
add it to priority queue,it gives an error, I know that my comparator makes this error, but I don't
know, how can I compare objects, please help me!
import java.util.Comparator;
public class PQueueTest {
public static void main(String [] args) {
DefaultComparator<Seller> o = new DefaultComparator<>();
Seller s = new Seller("ali", 125, 200);
Seller s1 = new Seller("hasan", 50, 100);
PriorityQueue<Seller> p = new PriorityQueue<>(o);
p.add(s);
p.add(s1);
System.out.println(p.removeMin());
System.out.println(p.removeMin());
}
}
class Node<E> {
private E element;
private Node<E> next;
public Node(E element, Node<E> next) {
this.element = element;
this.next = next;
}
public void setNext(Node<E> next) {
this.next = next;
}
public void setElement(E element) {
this.element = element;
}
public Node<E> getNext() {
return next;
}
public E getElement() {
return element;
}
}
class DefaultComparator<E> implements Comparator<E> {
#Override
public int compare(E a, E b) {
return ((Comparable<E>) a).compareTo(b);
}
}
class PriorityQueue<E> {
private int size;
private Node<E> front;
private DefaultComparator<E> c;
public PriorityQueue(Comparator<? super E> o) {
size = 0;
front = null;
c = (DefaultComparator<E>) o;
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
public void add(E element) {
Node<E> v = new Node<>(element, null);
if (isEmpty()) {
front = v;
}
if (size >= 1) {
Node<E> temp = front;
int comp = c.compare(element, temp.getElement());
while (comp >= 0 && temp.getNext() != null) {
temp = temp.getNext();
comp = c.compare(element, temp.getElement());
}
if (comp < 0) {
// E x = temp.getElement();
v.setNext(temp);
if (temp == front)
front = v;
else {
Node<E> tmp = front;
while (tmp.getNext() != temp) {
tmp = tmp.getNext();
}
tmp.setNext(v);
}
}
if (comp >= 0)
temp.setNext(v);
}
size++;
}
public E removeMin() {
E remove = front.getElement();
front = front.getNext();
size--;
return remove;
}
public E removeMax() {
Node<E> tmp = front;
while (tmp.getNext().getNext() != null) {
tmp = tmp.getNext();
}
E remove = tmp.getNext().getElement();
tmp.setNext(null);
size--;
return remove;
}
public E peekMin() {
E remove = front.getElement();
return remove;
}
public E peekMax() {
Node<E> tmp = front;
while (tmp.getNext().getNext() != null) {
tmp = tmp.getNext();
}
E remove = tmp.getNext().getElement();
return remove;
}
}
class Seller {
private String name;
private long price;
private int stock;
public Seller(String name, long price, int stock) {
this.name = name;
this.price = price;
this.stock = stock;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(long price) {
this.price = price;
}
public void setStock(int stock) {
this.stock = stock;
}
public String getName() {
return name;
}
public long getPrice() {
return price;
}
public int getStock() {
return stock;
}
}
class Buyer {
private String name;
private long price;
private int stock;
public Buyer(String name, long price, int stock) {
this.name = name;
this.price = price;
this.stock = stock;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(long price) {
this.price = price;
}
public void setStock(int stock) {
this.stock = stock;
}
public String getName() {
return name;
}
public long getPrice() {
return price;
}
public int getStock() {
return stock;
}
}

First of all: The error is that the cast to Comparable fails. I.e., this line of code:
return ((Comparable<E>)a).compareTo(b);
The reason for that is, that a (in your case, an instance of Seller) does not implement the Comparable interface. You want to compare instances of Seller, so Seller needs to implement the interface (and the corresponding methods):
class Seller implements Comparable<Seller> {
However you should be aware that Comparator and Comparable are usually two opposing concepts. While the implementation of Comparable allows instances of a class to compare themselves with other instances of that class, with a Comparator this comparison is encapsuled inside another class. Combining those concept usually makes no sense.
So you should
Understand what, why and how you should compare
Decide on one of the two concepts (Comparable or Comparator). Googling this should bring up good results.
If it's the Comparator, assert that only those types can be passed to your Comparator that can be handled by it (hint: take a look at the generic parameter)
And last but not least: Take a look at the warnings your IDE gives you about type safety. Understand them and you will find the major flaw in your code.

Related

Have a Queue with Generics implementation print specific Object attributes

I have created a simple Queue of type which is also contains a print() function to it.
public class ArrayQueue implements Queue {
private T[] theArray;
private int currentSize;
private int front;
private int back;
private static final int DEFAULT_CAPACITY = 10;
public ArrayQueue() {
theArray = (T[]) new Object[DEFAULT_CAPACITY];
currentSize = 0;
front = 0;
back = -1;
}
public boolean isEmpty() {
return currentSize == 0;
}
public T dequeue() throws EmptyQueueException {
if (isEmpty())
throw new EmptyQueueException("ArrayQueue dequeue error");
T returnValue = theArray[front];
front = increment(front);
currentSize--;
return returnValue;
}
public void enqueue(T x) {
if (currentSize == theArray.length)
doubleQueue();
back = increment(back);
theArray[back] = x;
currentSize++;
}
private int increment(int x) {
if (++x == theArray.length)
x = 0;
return x;
}
public void print() {
if (isEmpty()) {
System.out.printf("Empty queue\n");
return;
}
System.out.printf("The queue is: ");
for (int i = front; i != back; i = increment(i)) {
System.out.print(theArray[i] + " ");
}
System.out.print(theArray[back] + "\n");
}
I have also created a Song object with 3 variables
public class Song {
private int id;
private String name;
private int likes;
public Song() {
this(1,"Test",10);
}
public Song(int id,String name, int likes) {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLikes() {
return likes;
}
public void setLikes(int likes) {
this.likes = likes;
}
Is there a way modify this function in order to print a specific object's information or do i need to write a different print method during my implementation?
For example i would like my Print method to show all the objects variables , if i call just like this is will only get the object pointer
ArrayQueue<Song> arrayQueue = new ArrayQueue<Song>();
Queue<Song> queue = arrayQueue; //arrayQueue instance is also a Queue
Song s = new Song();
arrayQueue.enqueue(s);
arrayQueue.print();
Result is
The queue is: Song#15db9742
My modification would print :
The queue is : 1 Test 10
You need to override the toString() method of Song.
For example, add this to Song:
#Override
public String toString() {
return id + " " + name + " " + likes;
}

compareTo with generic linkedList

I am new to java and i have encountered a problem while making a generic class with comparable interface. In the sortedInsert method of LinkedList class it gives error on head.value.compareTo(new_node.value), i am making an object of Linkedlist class in main so , according to my understanding head.value should give me an employee object for which i am calling compareTo . but still it gives me this error . is there anything i understood incorrectly ? or making a mistake in this code .
cannot find symbol
symbol: method compareTo(T)
public class Employee implements Comparable<Employee>
{
private int empID;
private String name;
private int salary;
private boolean manager;
private int subordinates;
public Employee()
{
empID = 0;
name = "";
salary = 0;
manager = false;
subordinates = 0;
}
public Employee(int id , String name , int salary , boolean manager , int sub)
{
empID = id;
this.name = name;
this.salary = salary;
this.manager = manager;
subordinates = sub;
}
public int GetID()
{
return this.empID;
}
public String GetName()
{
return this.name;
}
#Override
public int compareTo(Employee other)
{
if (this.empID < other.empID)
{
return -1;
}
else if (this.empID > other.empID)
{
return 1;
}
else
{
return 0;
}
}
public class LinkedList<T>
{
private int count;
private Node<T> head;
private class Node<T>
{
public T value;
public Node<T> next;
public Node(T data)
{
this.value = data;
this.next = null;
}
}
LinkedList()
{
count = 0;
head = null;
}
void sortedInsert(T data)
{
Node<T> current;
Node<T> new_node = new Node<T>(data);
/* Special case for head node
head.value >= newNode*/
if (head == null || (head.value.compareTo(new_node.value) == 1 || head.value.compareTo(new_node.value) == 0))
{
new_node.next = head;
head = new_node;
}
else {
current = head;
while (current.next != null && (current.next.value.compareTo(new_node.value) == -1))
current = current.next;
new_node.next = current.next;
current.next = new_node;
}
}
You could try to switch to this:
public class LinkedList<T extends Comparable<T>>
The head.value variable is not necessarily something that implements Comparable interface. You need to either define your LinkedList<T> such that it must implement Comparable (see #algrid's answer) or cast it when using the compareTo method.

The type Lista is not generic; My list is correct?

Hi i having some trouble with: error
The type Lista is not generic; it cannot be parameterized with arguments "Integer"
My files tests:
public class testy {
public static void main(String[] args) {
Lista<Integer> l = new Lista<Integer>();
l.add(5);
l.add(7);
//System.out.println(l.removeFirst());
}
}
List :
public class Lista implements Serializable{
ListaS<T> Lista;
public Lista() {
Lista = new ListaS<T>(null, Lista, Lista);
Lista.setNext(Lista);
Lista.setPrevious(Lista);
}
public int Rozmiar(){
int counter = 0;
if(nastepny == null)
return counter;
else{
ListaS<T> tmp = counter;
do{
next = next.wezNastepny();
counter++;
}while(tmp != previous);
}
return counter;
}
public boolean Empty(){
if(Size()== 0 )
return true;
else
return false;
}
public void addStart(T wartosc){
ListaS<T> nowy = new ListaS<T>(wartosc);
if(next == null){
next=newnode;
next=newnode;
nowy.setNext(null);
nowy.setPrevious(null);
}else{
nowy.setNext(nastepny);
next.setPrevious(nowy);
next = nowy;
}
}
public void addEnd(T wartosc){
ListS<T> nowy = new ListaS<T>(value);
if(previous == null){
next=nowy;
previous =nowy;
newnode.setNext(null);
newnode.setPrevious(null);
}else{
newnode.setPrevious(previous);
previous.setNext(nowy);
previous=nowy;
}
public E removeFirst() {
if (size == 0) throw new NoSuchElementException();
ListS tmp = next;
next = next.getNext();
next.setNext = null;
System.out.println("deleted: "+tmp.value);
return tmp.wezWartosc();
}
}
And the last one
public class ListaS<T> implements Serializable{
T value;
ListaS<T> next;
ListaS<T> previous;
ListaS(T value, ListaS<T> next, ListaS<T> poprzedni) {
this.value = value;
this.next = next;
this.previous = previous;
}
T getValue() {
return value;
}
public void setNext(ListaS<T> nastepny) {
this.next = next;
}
public ListaS<T> getPrevious() {
return previous;
}
public void setPrevious(ListaS<T> poprzedni) {
this.previous = previous;
}
public void setValue(T value) {
this.value = value;
}
public ListaS<T> getNext() {
return next;
}
}
Ok if we solve first problem could some one tell me my function are ok?
And how i should write removeLast()?
Just convert your Lista class definition in public class Lista<T> implements Serializable

How to sort a custom Linked List in Java?

I am working on a custom Linked List based on Crunchify's implementation to display list of Employee. As of now I can add new Employee or remove existing Employee from the list. However, my project requires adding a sorting method that would not be based on Collections.sort(). My teacher wants this sorting method to be custom, so this is quite difficult for me. Is there anyway to sort this list by first name that is easy to code (I'm completely new to object oriented programming)?
Here is my custom Linked List:
import java.util.Scanner;
import java.io.IOException;
public class MyLinkedListTest2 {
public static MyLinkedList linkededList;
public static void main(String[] args) {
linkededList = new MyLinkedList();
linkededList.add(new Employee("Agness", "Bed", 2000.0, 32));
linkededList.add(new Employee("Adriano", "Phuks", 4000.0, 16));
linkededList.add(new Employee("Panda", "Mocs", 6000.0, 35));
System.out.println(linkededList);
//OPTIONS
Scanner scanner = new Scanner(System.in);
int selection;
do {
System.out.println("OPTIONS:\n[1] ADD EMPLOYEE\n[2] REMOVE EMPLOYEE\n[3] SORT \n[4] EXIT\n");
selection = scanner.nextInt();
switch (selection) {
case 1:
System.out.println("Name:");
scanner.nextLine();
String name = scanner.nextLine();
System.out.println("Surname:");
String surname = scanner.nextLine();
System.out.println("Salary:");
double salary = scanner.nextDouble();
System.out.println("Experience:");
int experience = scanner.nextInt();
linkededList.add(new Employee(name, surname, salary, experience));
System.out.println(linkededList);
break;
case 2:
System.out.println("Which row do you want to remove?");
int choice = scanner.nextInt();
if (choice == 0)
System.out.println("No such row exists");
else if (choice > linkededList.size())
System.out.println("No such row exists");
else
linkededList.remove(choice - 1);
System.out.println(linkededList);
break;
case 3:
System.out.println("SORT BY: 1.NAME\t2.SURNAME\t3.SALARY\t4.EXPERIENCE\n");
//In this section sorting algorithm should be added
break;
case 4:
break;
default:
System.out.println("Wrong choice");
}
} while (selection != 4);
}
}
class MyLinkedList<Employee> {
private static int counter;
private Node head;
public MyLinkedList() {
}
public void add(Object data) {
if (head == null) {
head = new Node(data);
}
Node myTemp = new Node(data);
Node myCurrent = head;
if (myCurrent != null) {
while (myCurrent.getNext() != null) {
myCurrent = myCurrent.getNext();
}
myCurrent.setNext(myTemp);
}
incrementCounter();
}
private static int getCounter() {
return counter;
}
private static void incrementCounter() {
counter++;
}
private void decrementCounter() {
counter--;
}
public void add(Object data, int index) {
Node myTemp = new Node(data);
Node myCurrent = head;
if (myCurrent != null) {
for (int i = 0; i < index && myCurrent.getNext() != null; i++) {
myCurrent = myCurrent.getNext();
}
}
myTemp.setNext(myCurrent.getNext());
myCurrent.setNext(myTemp);
incrementCounter();
}
public Object get(int index){
if (index < 0)
return null;
Node myCurrent = null;
if (head != null) {
myCurrent = head.getNext();
for (int i = 0; i < index; i++) {
if (myCurrent.getNext() == null)
return null;
myCurrent = myCurrent.getNext();
}
return myCurrent.getData();
}
return myCurrent;
}
public boolean remove(int index) {
if (index < 1 || index > size())
return false;
Node myCurrent = head;
if (head != null) {
for (int i = 0; i < index; i++) {
if (myCurrent.getNext() == null)
return false;
myCurrent = myCurrent.getNext();
}
myCurrent.setNext(myCurrent.getNext().getNext());
decrementCounter();
return true;
}
return false;
}
public int size() {
return getCounter();
}
public String toString() {
String output = "";
if (head != null) {
Node myCurrent = head.getNext();
while (myCurrent != null) {
output += myCurrent.getData().toString();
myCurrent = myCurrent.getNext();
}
}
return output;
}
public void compare(int index){
Node myCurrent = head.getNext();
if(myCurrent != myCurrent.getNext())
myCurrent = head;
else
myCurrent = myCurrent.getNext();
}
private class Node {
Node next;
Object data;
public Node(Object dataValue) {
next = null;
data = dataValue;
}
#SuppressWarnings("unused")
public Node(Object dataValue, Node nextValue) {
next = nextValue;
data = dataValue;
}
public Object getData() {
return data;
}
#SuppressWarnings("unused")
public void setData(Object dataValue) {
data = dataValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
}
Also, here is my Employee class that the list is based on:
public class Employee
{
private String firstName;
private String lastName;
private double salary;
private int experience;
public Employee(String firstName, String lastName, double salary, int experience)
{
this.firstName = firstName;
this.lastName = lastName;
this.salary = salary;
this.experience = experience;
}
public String getFirstName()
{
return firstName;
}
public String getLastName()
{
return lastName;
}
public double getSalary()
{
return salary;
}
public int getExperience()
{
return experience;
}
#Override
public String toString()
{
String ret = "\n" +"Name: "+firstName +" | Surname: "+lastName +" | Salary: "+salary + " | Experience: "+experience +"\n";
return ret;
}
}
The code is compiling now, but maybe you have some recommendation regarding this implementation of Linked List? I would be grateful if someone comes up with a solution for sorting, since with this my project will be completed. Only Comparable can be used, while Collections.sort() method cannot be implemented due to project's requirements.
You can define your own EmployeeComparator that implements Comparator<Employee> (see comparator) and use it like following :
SortedSet<Employee> set = new TreeSet<Employee>(new EmployeeComparator());
set.addAll(employees);
Since you need to implement the sorting yourself, one of the easiest way could be so compare each list node with the next one and swap them if they are not in sorted order. You need to do this until there is any such out of order nodes left in the list.
You can see bubble sort implementation for an idea on how this works.

Why do I find extra reference objects to the linked list?

I've been working on the exercise to better understand Linked List.
My output is:
***DISPALY NAMES
Miki
null
Arek
null
Magi
null
Problem: display nulls between names.
Tried to do: Wrote bunch of print statements and it looks like is adding extra Name reference object to the list. I was trying to find error in the add method but logically everything fines for me.
I am not allowed to use LinkedList API.
Thank you for your help.
<pre> <code>
public class NameTest {
public static void main(String[] args) {
NameList<Name> n = new NameList<Name>();
Name n1 = new Name(1,"Miki");
Name n2 = new Name(2, "Arek");
Name n3 = new Name(3, "Magi");
n.addName(n1);
n.addName(n2);
n.addName(n3);
n.displayNames();
System.out.println("*******************\n");
}
}
public class Name {
private int nameId;
private String firstName;
private Name next;
public Name() { }
public Name(int nameId, String firstName) {
super();
this.nameId = nameId;
this.firstName = firstName;
this.next = new Name();
}
public int getNameId() {
return nameId;
}
public void setNameId(int nameId) {
this.nameId = nameId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Name getNext() {
return next;
}
public void setNext(Name next) {
this.next = next;
}
}
public class NameList<T extends Name> {
private T head;
private int value;
public NameList() {
head = null;
value = 0;
}
public T getHead() {
return head;
}
public void setHead(T head) {
this.head = head;
}
public void addName(T name) {
if(head == null) {
setHead(name);
value++;
}
else {
T curr = getHead();
while(curr.getNext() != null) {
curr = (T) curr.getNext();
}
curr.setNext(name);
value++;
}
}
public void displayNames() {
System.out.println("***DISPLAY NAMES ");
T curr = getHead();
while(curr.getNext() != null ) {
System.out.println(curr.getFirstName());
curr = (T) curr.getNext();
}
if(curr.getNext() == null) {
System.out.println(curr.getFirstName());
}
}
Instance variable next in the class name should be like this: private Name next; I am sorry for confusion. I made correction in the code above.
Your problem is this line.
this.next = new Name();
You're adding a new "empty object" onto the back of every Name that you add. Remove it and you'll get the desired result. (I assume you also have Name extends Employee in there somewhere, otherwise this doesn't compile).

Categories