在Java中比较两个比较器对象

时间:2012-12-03 12:33:54

标签: java

如果我执行以下操作

myObject.myMethod(myClass.getComparator());

public void myMethod(Comparator<? super myOtherObject> comparator) {
if (comparator.equals(myClass.getComparator()) {
 //do sth
}
}

和myClass

   static Comparator<ListItem> getComparator() {
        return new Comparator<myOtherObject>() {
            public int compare(myOtherObjectitem1, myOtherObjectitem2) {
                return (Integer.valueOf(myOtherObject.getRating()).compareTo(Integer.valueOf(myOtherObject.getRating())));
            }
        };
    }

然后“// do sth”不会被执行。所以我从getComparator获得的对象两次是不同的。怎么可能?有没有机会看到哪个比较器“myMethod”得到了?

2 个答案:

答案 0 :(得分:3)

您在此行上调用equals方法:

if (comparator.equals(myClass.getComparator())

由于您尚未在Comparator类(这是一个匿名内部类)上显式定义此方法,因此默认为从Object继承的版本 - 它认为两个引用只有在它们完全相同时才相等对象

你的getComparator()方法声明return new Comparator() { ... },所以它调用构造函数并在每次调用时创建一个新对象。因此,对getComparator的一次调用的结果将是一个不同的对象,因此不会被认为是另一个调用的结果。

我可以想到两种可能的方法来更改代码,以便相等测试返回true:

  1. 仅创建一次比较器,并从中返回相同的对象 getComparator。这将涉及一些有点类似的变化 在myClass中跟随:

        private static Comparator<ListItem> cmp = new Comparator<myOtherObject>() {
           public int compare(myOtherObjectitem1, myOtherObjectitem2) {
                return (Integer.valueOf(myOtherObject.getRating()).compareTo(Integer.valueOf(myOtherObject.getRating())));
            }
        };
    
        static Comparator<ListItem> getComparator() {
            return cmp;
        }
    
  2. 提供明确的equals()实现(理想情况下也是hashCode()实现)。然后,您可以精确控制哪些对象被视为与您的一个比较器相等。如果为比较器定义具体类而不是匿名内部类,这可能会容易得多。


  3. 但是,在一天结束时,我担心你的做法可能不对。两个比较器彼此相等意味着什么?我觉得这对于除数据类之外的任何事情都是一个含糊不清的概念,我会对使用Object.equals方法犹豫不决。

    (例如,如果相等意味着“他们将按相同的顺序对列表进行排序”,那么我会在比较器类中添加一个名为isEquivalentSortOrder的方法或类似的方法。这样你就可以准确地指定你的意思是什么,而不必依赖于“同样”的羊毛定义。)

答案 1 :(得分:0)

为什么不在myClass内创建Comparator静态变量,如:

class myClass{
    public static Comparator<ListItem> = new Comparator<myOtherObject>() {
        public int compare(myOtherObjectitem1, myOtherObjectitem2) {
            ...
        }
    };
}