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

发布于 2024-09-19 08:04:53 字数 807 浏览 2 评论 0原文

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

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”的值不同。我在这里做错了什么?

I need to sort lists of objects with a non-static comparator that uses a value from it's outer object field.

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

But for some reason this does not work properly. When I uncomment the println line in the comparator, it shows that the references are to A objects, but they are different within one sort() call, therefore the value of "x" is different. What am I doing wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

Hello爱情风 2024-09-26 08:04:53

你能解释一下为什么你需要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();

Can you explain why do you need the Comparatorto be non-static? Why not just the following?

    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();
千秋岁 2024-09-26 08:04:53

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

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

That depends on what you want to achieve. The code above doesn't work because you use different values of x when you create your A instances.

Each time, you create an instance of A, you also create an instance of the comparator which is tied to the instance of A. That means the x in the compare() method is either o1.x or o2.x.

I suggest to create a new class that implements the comparator and which has a field x to make it independent of 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);
    }
}
猫烠⑼条掵仅有一顆心 2024-09-26 08:04:53

首先让我们看看 scoreComparator 做了什么。该行

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

也可以写为

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

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

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

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

Let's see first what the scoreComparator does. The line

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

could be also written as

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

which means the the sign of x -- positive or negative inverts comparation result will revert the ordering in the sorting list.

Casting to int is added to ensure integer overflow if values of x and o1.x or x and o2.x are too big. Again, the sign of x will just revert the ordering.

Since both var_1 and var_2 have positive values for the field x we can conclude that the second scenario causes integer overflow and different ordering. var_1.x equals to 1, and var_2.x equals to 5 which makes integer overflowing five times more probable in the latter case.

内心激荡 2024-09-26 08:04:53

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

I'm not 100% sure what you want to achieve by this design, but this is a very bad design. If you want a non-static comparator inside the same class type, try going for compareTo rather than compare. Otherwise, put the compare method in a separate class as @Aaron suggested.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文