1

如果我执行以下操作

myObject.myMethod(myClass.getComparator());

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

在我的班级

   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”得到了?

4

2 回答 2

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()理想情况下也是一个)。然后,您可以准确控制哪些对象被认为等于您的比较器之一。如果您为比较器定义一个具体类而不是匿名内部类,这可能会容易得多。


不过,归根结底,我担心您的方法可能不正确。两个比较器彼此相等是什么意思?我觉得这对于数据类以外的任何东西都是一个模棱两可的概念,我会犹豫是否要使用这种Object.equals方法。

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

于 2012-12-03T12:36:54.280 回答
0

为什么不在内部创建类似myClass的静态变量Comparator

class myClass{
    public static Comparator<ListItem> = new Comparator<myOtherObject>() {
        public int compare(myOtherObjectitem1, myOtherObjectitem2) {
            ...
        }
    };
}
于 2012-12-03T12:39:25.013 回答