Java:从非静态比较器引用到它的外部类字段

时间:2010-09-14 07:01:00

标签: java reference comparator

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

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 个答案:

答案 0 :(得分:1)

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

    static class MyComparator implements Comparator {
        public compare(A o1, A o2) {
            // System.out.println("this: " + this);
            return o1.x - o2.x;
        }
    }

    public Comparator scoreComparator = new MyComparator();

答案 1 :(得分:0)

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

每次创建A的实例时,您还会创建一个与A实例绑定的比较器实例。这意味着x方法中的compare()o1.xo2.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);
    }
}

答案 2 :(得分:0)

让我们先看看scoreComparator的作用。这条线

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

也可以写成

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

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

如果intxo1.xx的值太大,则会添加转换为o2.x以确保整数溢出。同样,x的符号只会恢复排序。

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

答案 3 :(得分:0)

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