1

我需要使用非静态比较器对对象列表进行排序,该比较器使用其外部对象字段中的值。

class A {
    public int x;
    public int y;
    public int z;

    public Comparator<A> scoreComparator = new Comparator<A>() {
        public compare(A o1, A o2) {
            // System.out.println("this: " + this);
            return (int) (x * o1.x - x * o2.x);
        }
    }

    public A(int _x, int _y, int _z) {
        x = _x;
        y = _y;
        z = _z;
    }
}

A var_1 = new A(1, 2, 3);
A var_2 = new A(5, 6, 7);
List<A> list = getMyListFromSomewhere();

// the following will produce different ordering
Collections.sort(list, var_1.scoreComparator);
Collections.sort(list, var_2.scoreComparator);

但由于某种原因,这不能正常工作。当我取消注释比较器中的 println 行时,它表明引用是对 A 对象的,但它们在一次 sort() 调用中是不同的,因此“x”的值是不同的。我在这里做错了什么?

4

4 回答 4

1

你能解释一下为什么你需要Comparator非静态的吗?为什么不只是以下?

    静态类 MyComparator 实现比较器 {
        公共比较(A o1,A o2){
            // System.out.println("this:" + this);
            返回 o1.x - o2.x;
        }
    }

    公共比较器 scoreComparator = new MyComparator();
于 2010-09-14T07:09:42.887 回答
0

我不是 100% 确定你想通过这个设计实现什么,但这是一个非常糟糕的设计。如果您想在同一类类型中使用非静态比较器,请尝试使用 compareTo 而不是比较。否则,按照@Aaron 的建议,将 compare 方法放在单独的类中。

于 2010-09-14T07:18:14.510 回答
0

这取决于你想要达到的目标。上面的代码不起作用,因为您x在创建A实例时使用了不同的值。

每次创建 的实例时A,也会创建与 的实例相关联的比较器实例A。这意味着方法xcompare()的 要么o1.x要么o2.x

我建议创建一个实现比较器的新类,并且它有一个x使其独立于的字段A

public class ScoreComparator implements new Comparator<A>() {
    private int x;
    public ScoreComparator(int x) { this.x = x; }
    public compare(A o1, A o2) {
        // System.out.println("this: " + this);
        return (int) (x * o1.x - x * o2.x);
    }
}
于 2010-09-14T07:11:20.030 回答
0

让我们先看看它做了什么scoreComparator。线

(int) (x * o1.x - x * o2.x)

也可以写成

(int) x * (o1.x - o2.x)

这意味着x--正或负反转比较结果的符号将恢复排序列表中的排序。

如果and或and的值太大,int则添加转换以确保整数溢出。同样, 的符号只会恢复排序。xo1.xxo2.xx

由于var_1var_2都具有该字段的正值,x我们可以得出结论,第二种情况会导致整数溢出和不同的排序。var_1.x等于1var_2.x等于5使整数在后一种情况下溢出的可能性增加五倍。

于 2010-09-14T07:15:16.877 回答