java 自定义对象比较器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15635714/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Custom object comparator
提问by Whizzil
I will try to get right to the point.
我会尽量切入正题。
I am having my custom Node objects, which have attribute Cost. I would want to sort those Node objects in ascending order by their attribute Cost.
我有我的自定义节点对象,它具有属性成本。我想按属性成本按升序对这些 Node 对象进行排序。
I was able to do so using PriorityQueue<Node> = new PriorityQueue<Node>(10000, new NodeComparator());
, but that way worked too slow for me, and now I am looking to do the same thing, only using TreeSet.
Anyways, if my constructor looks like this TreeSet<Node> = new TreeSet<Node>(new NodeComparator());
, the program seems to skip vast amount of Node objects, seemingly treating them as they are the same. Which they are not. I am assuming there might be some hashCode issues about, but I am not sure, and I don't know how to resolve it at this moment.
我可以使用PriorityQueue<Node> = new PriorityQueue<Node>(10000, new NodeComparator());
,但这种方式对我来说太慢了,现在我想做同样的事情,只使用 TreeSet。无论如何,如果我的构造函数看起来像这样TreeSet<Node> = new TreeSet<Node>(new NodeComparator());
,程序似乎会跳过大量 Node 对象,似乎将它们视为相同的对象。他们不是。我假设可能存在一些 hashCode 问题,但我不确定,目前我不知道如何解决。
To be concise, I just want my Nodes in TreeSet to be ordered in ascending way by Cost attribute. Here is my NodeComparator class:
简而言之,我只希望 TreeSet 中的节点按成本属性升序排列。这是我的 NodeComparator 类:
public class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node n1, Node n2) {
// TODO Auto-generated method stub
if(n1.cost > n2.cost) return 1;
else if(n1.cost < n2.cost) return -1;
else return 0;
}
}
And here is my Node class:
这是我的 Node 类:
public class Node{
public State state;
public int cost;
public Node(State s, int Cost){
this.state = s;
this.cost = Cost;
}
public State getState(){
return this.state;
}
public int getCost(){
return this.cost;
}
}
I will provide you with my State class aswell.
我也会为您提供我的 State 课程。
public class State {
public int lamp;
public ArrayList<Integer> left;
public State(ArrayList<Integer> Left, int Lamp){
lamp = Lamp;
left = Left;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + lamp;
result = prime * result + ((left == null) ? 0 : left.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
State other = (State) obj;
if (lamp != other.lamp)
return false;
if (left == null) {
if (other.left != null)
return false;
} else if (!left.equals(other.left))
return false;
return true;
}
}
回答by Pshemo
TreeSet
uses TreeMap
to store values. Your problem is that TreeMap
instead equals
uses result of comparatorto check if element is already in map. Because of that you need to include state of steate
field in compare
method like
TreeSet
使用TreeMap
到存储值。你的问题是,TreeMap
而不是equals
使用比较结果来检查元素已经在地图中。因此,您需要steate
在compare
方法中包含字段状态,例如
@Override
public int compare(Node n1, Node n2) {
// TODO Auto-generated method stub
if(n1.cost > n2.cost) return 1;
else if(n1.cost < n2.cost) return -1;
else return ( n1.equals(n2)? 0 : 1);
}
回答by SudoRahul
Set
by default eliminates duplicates. You need to override your equals()
& hashCode()
in your Node
class.
Set
默认情况下消除重复项。你需要在你的班级中覆盖你的equals()
& 。hashCode()
Node