定制对象比较器

时间:2013-03-26 11:17:31

标签: java collections treeset

我会努力做到这一点。

我有我的自定义Node对象,它们具有属性Cost。我想按属性Cost。

按升序对这些Node对象进行排序

我能够使用PriorityQueue<Node> = new PriorityQueue<Node>(10000, new NodeComparator());这样做,但这种方式对我来说太慢了,现在我想做同样的事情,只使用TreeSet。 无论如何,如果我的构造函数看起来像这个TreeSet<Node> = new TreeSet<Node>(new NodeComparator());,程序似乎跳过了大量的Node对象,似乎将它们视为相同。他们不是。我假设可能存在一些hashCode问题,但我不确定,我现在不知道如何解决它。

简而言之,我只是希望TreeSet中的节点按Cost属性按升序排序。 这是我的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;
    }

}

这是我的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;
    }
}

我也会为你提供国家课程。

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;
    }
}

2 个答案:

答案 0 :(得分:5)

TreeSet uses TreeMapstore values。您的问题是TreeMap而不是equals uses result of comparator来检查元素是否已经在地图中。因此,您需要在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);
}

答案 1 :(得分:1)

Set默认消除重复。您需要覆盖equals()&amp; hashCode()课程中Node