Reputation: 63
I'm having troubles adding an Object Node to my PriorityQueue and I cant figure out why. When I add Node a, it has no problem.
PriorityQueue<Node> q = new PriorityQueue<Node>();
Node a = new Node('a', 1);
q.add(a);
but if I add a second Node, it throws an exception saying "java.lang.ClassCastException: Node cannot be cast to java.lang.Comparable"
PriorityQueue<Node> q = new PriorityQueue<Node>();
Node a = new Node('a', 1);
Node b = new Node('b', 2);
q.add(a);
q.add(b);
My Node class is below:
public class Node {
public int count;
public char character;
public Node left;
public Node right;
public Node(char character, int count) {
this(character, count, null, null);
}
public Node(char character, int count, Node left, Node right) {
this.count = count;
this.character = character;
this.left = left;
this.right = right;
}
public int compareTo(Node other) {
return this.count - other.count;
}
}
I guess I'm just confused why it can add Node a but not add Node b. I looked up what ClassCastException is and I dont really see that I did that kind of exception since I'm adding a type Node to a PriorityQueue of type Nodes. I would appreciate any help. Thank you!
Upvotes: 1
Views: 697
Reputation: 1198
Node
should inherit Comparable
as follows:
public class Node implements Comparable<Node> {
...
@Override
public int compareTo(Node n) {
...
}
}
Upvotes: 1
Reputation: 765
implements Comparable<Node>
is missing in your class Node
:
public class Node implements Comparable<Node> {
public int count;
public char character;
public Node left;
public Node right;
public Node(char character, int count) {
this(character, count, null, null);
}
public Node(char character, int count, Node left, Node right) {
this.count = count;
this.character = character;
this.left = left;
this.right = right;
}
@Override
public int compareTo(Node other) {
return this.count - other.count;
}
}
Upvotes: 1
Reputation: 46181
From the documentation of PriorityQueue
:
An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a
Comparator
provided at queue construction time, depending on which constructor is used. A priority queue does not permitnull
elements. A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so may result inClassCastException
). [emphasis added]
The documentation of PriorityQueue#add(E)
states it can throw:
ClassCastException
- if the specified element cannot be compared with elements currently in this priority queue according to the priority queue's ordering
And you create your PriorityQueue
using the no-argument constructor, whose documentation states:
Creates a
PriorityQueue
with the default initial capacity (11
) that orders its elements according to their natural ordering.
For an object to have a natural ordering it must implement the Comparable
interface. Since your Node
class does not implement Comparable
you get a ClassCastException
when adding the second element (due to there now being enough elements to start comparing them). There are at least two solutions:
Have Node
implement Comparable<Node>
:
public class Node implements Comparable<Node> {
// fields and other methods omitted for brevity
@Override // annotation forces compiler to check if method actually overrides anything
public int compareTo(Node other) {
// compare 'this' and 'other' based on their properties and return result...
}
}
Pass a Comparator
implementation when creating the PriorityQueue
:
PriorityQueue<Node> queue = new PriorityQueue<>((left, right) -> /* compare */);
Also see Java : Comparable vs Comparator [duplicate].
Upvotes: 1
Reputation: 11
Either Node
must implement Comparable
(as some answers suggest), or a Comparator
must be provided when creating the PriorityQueue
- according javadoc
An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a
Comparator
provided at queue construction time, depending on which constructor is used. A priority queue does not permit null elements. A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so may result inClassCastException
).
Upvotes: 1
Reputation: 794
The first one worked because it's the only one. From the second it needs to compare it against the first one to know where to place it on the priority queue. You need to implement the interface Comparable on your Node class and implement the compare (a, b) method. Then the Priority queue will know how to properly order the items.
Upvotes: 5