将比较器与 Java 中的对象列表一起使用
Using Comparator with List of Objects in Java
我想按键(字符串类型)对 AVLNode 类型的对象进行排序。我实例化了一个 Comparator 并想在 String 属性上应用 compareTo
方法。但是,我的 IDE 显示错误 Cannot resolve method compareTo
。我不明白为什么我不能在这一点上对字符串使用 compareTo
方法。
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);
}
}
}
这是我的 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;
}
}
我做错了什么?
AVLNode
是通用的,用 K
和 V
参数化。在你的 Comparator<AVLNode>
中,AVLNode
是原始的。也就是说,K
和 V
是未知的。这意味着编译器实际上不知道 K
是否为 Comparable
.
尝试制作它 Comparator<AVLNode<String, ?>>
。
无关,但也用new AVLNode<>(...)
。
您正在比较器中声明原始 AVLNode
对象。这就是为什么只有 class Object
的方法可用于 AVLNode.getKey()
.
将您的比较器声明更改为此
Comparator<AVLNode<String, Cuboid>> myComp2 = new Comparator<AVLNode<String, Cuboid>>() {
@Override
public int compare(AVLNode<String, Cuboid> o1, AVLNode<String, Cuboid> o2) {
return 0;
}
};
K
in AVLNode
不包括对 Comparable
的遵从(compareTo
可能来自哪里)
您可以向 K
添加一个额外的约束,以便所有键都必须符合 Comparable
,例如...
public class AVLNode<K extends Comparable<K>, V> {
//...
}
这将限制置于 AVLNode
本身,因此请注意(所有键必须实现 Comparable
)
如上所述,编译器不知道 n1.getKey()
returns String
,因此它假定将返回 Object
。无论如何,Collections.sort()
可以通过这种方式修改您的代码,请参见下文。您还没有提供 Cuboid
的实现,因此我将其替换为字符串。
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 +
'}';
}
}
输出:
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。实际上,我检查了@MadProgrammer 的建议。它也是这样工作的
...
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> {
...
编译器只需要知道您的 key
实现了 Comparable
不要使用原始类型,最好这样写:
Comparator<AVLNode<Type1, Type2> comparator ...
例如:
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());
}
};
顺便说一句,您可以使用Comparator.comparing(...)
代替匿名class,例如:
Comparator<AVLNode<String, Cuboid>> comparator = Comparator.comparing(AVLNode::getKey);
我想按键(字符串类型)对 AVLNode 类型的对象进行排序。我实例化了一个 Comparator 并想在 String 属性上应用 compareTo
方法。但是,我的 IDE 显示错误 Cannot resolve method compareTo
。我不明白为什么我不能在这一点上对字符串使用 compareTo
方法。
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);
}
}
}
这是我的 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;
}
}
我做错了什么?
AVLNode
是通用的,用 K
和 V
参数化。在你的 Comparator<AVLNode>
中,AVLNode
是原始的。也就是说,K
和 V
是未知的。这意味着编译器实际上不知道 K
是否为 Comparable
.
尝试制作它 Comparator<AVLNode<String, ?>>
。
无关,但也用new AVLNode<>(...)
。
您正在比较器中声明原始 AVLNode
对象。这就是为什么只有 class Object
的方法可用于 AVLNode.getKey()
.
将您的比较器声明更改为此
Comparator<AVLNode<String, Cuboid>> myComp2 = new Comparator<AVLNode<String, Cuboid>>() {
@Override
public int compare(AVLNode<String, Cuboid> o1, AVLNode<String, Cuboid> o2) {
return 0;
}
};
K
in AVLNode
不包括对 Comparable
的遵从(compareTo
可能来自哪里)
您可以向 K
添加一个额外的约束,以便所有键都必须符合 Comparable
,例如...
public class AVLNode<K extends Comparable<K>, V> {
//...
}
这将限制置于 AVLNode
本身,因此请注意(所有键必须实现 Comparable
)
如上所述,编译器不知道 n1.getKey()
returns String
,因此它假定将返回 Object
。无论如何,Collections.sort()
可以通过这种方式修改您的代码,请参见下文。您还没有提供 Cuboid
的实现,因此我将其替换为字符串。
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 +
'}';
}
}
输出:
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。实际上,我检查了@MadProgrammer 的建议。它也是这样工作的
...
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> {
...
编译器只需要知道您的 key
实现了 Comparable
不要使用原始类型,最好这样写:
Comparator<AVLNode<Type1, Type2> comparator ...
例如:
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());
}
};
顺便说一句,您可以使用Comparator.comparing(...)
代替匿名class,例如:
Comparator<AVLNode<String, Cuboid>> comparator = Comparator.comparing(AVLNode::getKey);