Reputation: 1684
I'd like to sort my objects of Type AVLNode by their key (type String). I instantiated a Comparator and want to apply the compareTo
Method on the String attribute. But, my IDE shows me the error Cannot resolve method compareTo
. I don't understand why I cant use the compareTo
method on a string an this point.
import java.util.*;
public class AVLTreeTest {
public static void main(String[] args){
Comparator<AVLNode>myComp2 = new Comparator<AVLNode>() {
@Override public int compare(AVLNode n1, AVLNode n2) {
return n1.getKey().compareTo(n2.getKey());
}
};
AVLNode<String, AVLNode> a1 = new AVLNode( "test3", new Cuboid (2,3,4,5,6,7) );
AVLNode<String, AVLNode> a2 = new AVLNode( "test2", new Cuboid (2,3,4,5,6,7) );
AVLNode<String, AVLNode> a3 = new AVLNode( "test8", new Cuboid (2,3,4,5,6,7) );
AVLNode<String, AVLNode> a4 = new AVLNode( "test1", new Cuboid (2,3,4,5,6,7) );
List<AVLNode> listOfNodes = new ArrayList<AVLNode>();
listOfNodes.add(a1);
listOfNodes.add(a2);
listOfNodes.add(a3);
listOfNodes.add(a4);
Collections.sort(listOfNodes, myComp2);
for (AVLNode node : listOfNodes){
System.out.println(node);
}
}
}
This is my AVLNode Class
public class AVLNode<K, V> {
private AVLNode<K, V> left, right, parent;
private int height = 1;
private K key;
private V value;
public AVLNode() {}
public AVLNode(K key, V value) {
this.key = key;
this.value = value;
}
public V getValue() {
return value;
}
public K getKey() {
return key;
}
}
What am I doing wrong?
Upvotes: 4
Views: 831
Reputation: 16246
Don't use raw types, better to write:
Comparator<AVLNode<Type1, Type2> comparator ...
For example:
Comparator<AVLNode<String, Cuboid>> myComp2 = new Comparator<>() {
@Override
public int compare(AVLNode<String, Cuboid> n1, AVLNode<String, Cuboid> n2) {
return n1.getKey().compareTo(n2.getKey());
}
};
By the way, you can use the Comparator.comparing(...)
instead of anonymous class, for example:
Comparator<AVLNode<String, Cuboid>> comparator = Comparator.comparing(AVLNode::getKey);
Upvotes: 4
Reputation: 1289
As mentioned above compiler doesn't know that n1.getKey()
returns String
, so it assumes that Object
will be returned. Anyway for Collections.sort()
to work your code can be modified this way, see below. You haven't provided implementation of your Cuboid
, so I replaced it with string.
public class AVLTreeTest {
public static void main(String[] args) {
Comparator myComp2 = new Comparator<AVLNode>() {
@Override
public int compare(AVLNode n1, AVLNode n2) {
return ((String)n1.getKey()).compareTo((String)n2.getKey());
}
};
AVLNode<String, AVLNode> a1 = new AVLNode("test3", "asd");
AVLNode<String, AVLNode> a2 = new AVLNode("test2", "bds");
AVLNode<String, AVLNode> a3 = new AVLNode("test8", "asdfas");
AVLNode<String, AVLNode> a4 = new AVLNode("test1", "asdfasdf");
List<AVLNode> listOfNodes = new ArrayList<AVLNode>();
listOfNodes.add(a1);
listOfNodes.add(a2);
listOfNodes.add(a3);
listOfNodes.add(a4);
Collections.sort(listOfNodes, myComp2);
for (AVLNode node : listOfNodes) {
System.out.println(node);
}
}
}
class AVLNode<K, V> {
private AVLNode<K, V> left, right, parent;
private int height = 1;
private K key;
private V value;
public AVLNode() {
}
public AVLNode(K key, V value) {
this.key = key;
this.value = value;
}
public V getValue() {
return value;
}
public K getKey() {
return key;
}
@Override
public String toString() {
return "AVLNode{" +
"left=" + left +
", right=" + right +
", parent=" + parent +
", height=" + height +
", key=" + key +
", value=" + value +
'}';
}
}
Output:
AVLNode{left=null, right=null, parent=null, height=1, key=test1, value=asdfasdf}
AVLNode{left=null, right=null, parent=null, height=1, key=test2, value=bds}
AVLNode{left=null, right=null, parent=null, height=1, key=test3, value=asd}
AVLNode{left=null, right=null, parent=null, height=1, key=test8, value=asdfas}
P.S. Actually, I checked @MadProgrammer suggestion. It works this way as well
...
Comparator myComp2 = new Comparator<AVLNode>() {
@Override
public int compare(AVLNode n1, AVLNode n2) {
return n1.getKey().compareTo(n2.getKey());
}
};
...
class AVLNode<K extends Comparable<K>, V> {
...
Compiler just needs to know that your key
implements Comparable
Upvotes: 1
Reputation: 347314
K
in AVLNode
doesn't not include a conformance to Comparable
(from where compareTo
might come from)
You could add an additional constraint to K
so that all keys must conform to Comparable
, something like...
public class AVLNode<K extends Comparable<K>, V> {
//...
}
This places the limitation onto AVLNode
itself, so beware (that all keys must implement Comparable
)
Upvotes: 2
Reputation: 8758
You are declaring raw AVLNode
objects in your comparator. That is why only methods of class Object
are available for AVLNode.getKey()
.
Change your Comparator declaration to this
Comparator<AVLNode<String, Cuboid>> myComp2 = new Comparator<AVLNode<String, Cuboid>>() {
@Override
public int compare(AVLNode<String, Cuboid> o1, AVLNode<String, Cuboid> o2) {
return 0;
}
};
Upvotes: 1
Reputation: 43689
AVLNode
is generic, parameterized with K
and V
. In your Comparator<AVLNode>
, AVLNode
is raw. That is, K
and V
are unknown. This means the compiler actually does not know if K
is Comparable
.
Try making it Comparator<AVLNode<String, ?>>
.
Unrelated, but also use new AVLNode<>(...)
.
Upvotes: 5