我需要使用非静态比较器对对象列表进行排序,该比较器使用来自其外部对象字段的值。
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”的值是不同的。我在这里做错了什么?
答案 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.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);
}
}
答案 2 :(得分:0)
让我们先看看scoreComparator
的作用。这条线
(int) (x * o1.x - x * o2.x)
也可以写成
(int) x * (o1.x - o2.x)
表示x
的符号 - 正或负反转比较结果将恢复排序列表中的排序。
如果int
和x
或o1.x
和x
的值太大,则会添加转换为o2.x
以确保整数溢出。同样,x
的符号只会恢复排序。
由于var_1
和var_2
都有字段x
的正值,我们可以得出结论,第二种情况会导致整数溢出和不同的排序。 var_1.x
等于1
,而var_2.x
等于5
,这使得整数在后一种情况下溢出的可能性增加了五倍。
答案 3 :(得分:0)
我不是100%确定你想要通过这种设计实现什么,但这是一个非常糟糕的设计。 如果您想在同一类类型中使用非静态比较器,请尝试使用compareTo而不是比较。否则,将比较方法放在@Aaron建议的单独的类中。