8

Java 提供了使用Comparator.

现在我的问题是为什么 java 不允许对 equals() 和 hashcode() 做同样的事情。

现在每个集合contains()方法都可以轻松地使用这个外部相等提供程序来检查对象是否相等。

4

3 回答 3

3

GuavaEquivalence课程,它几乎可以满足您的要求。

您甚至可以将对象包装在 anEquivalence中以使用更好的 hashCode() equals() 实现来装饰对象(例如,如果您想使用带有错误 equals() hashCode() 的对象作为 Map 键但没有访问权限到消息来源)

这是一个示例:数组没有正确实现 equals() 和 hashCode(),但这里是 char 数组的等价:

private static final Equivalence<char[]> CHAR_ARRAY_EQUIV = new Equivalence<char[]>(){

    @Override
    protected boolean doEquivalent(char[] a, char[] b) {
        return Arrays.equals(a, b);
    }

    @Override
    protected int doHash(char[] chars) {
        return Arrays.hashCode(chars);
    }
};

示例代码:

final char[] first ={'a','b'};
final char[] second ={'a','b'};

Assert.assertFalse(first.equals(second));
Assert.assertFalse(first.hashCode() == second.hashCode());

final Wrapper<char[]> firstWrapped = CHAR_ARRAY_EQUIV.wrap(first);
final Wrapper<char[]> secondWrapped = CHAR_ARRAY_EQUIV.wrap(second);

Assert.assertTrue(firstWrapped.equals(secondWrapped));
Assert.assertTrue(firstWrapped.hashCode() == secondWrapped.hashCode());
于 2012-09-12T14:42:05.207 回答
0

equals并且hashCode是对于给定的不会改变的概念Object只有实现者知道根据这些方法的规则应该使用哪些值。一旦他决定了那些,他们就定义了对象的身份,因此永远不应该改变。

另一方面,比较可能高度依赖于上下文。您可以通过实现来定义“自然”顺序Comparable。但这不能针对不同的上下文而改变。假设您有一个可以按姓氏、名字、邮政编码、城市排序的联系人列表……您可以通过提供单独Comparator的 s (或参数化的 s Comparator)轻松地做到这一点。但它不是对象本身固有的,因此它应该是它自己的一个类(它可以实现为静态内部类,具体取决于您的代码约定)。

于 2012-09-12T14:36:37.940 回答
0

Comparator 接口用于在对集合进行排序时比较对象,它的 compare() 方法返回一个“int”,意思是,比较以一个 int 值结束,可以用来指示对象在排序集合中的位置。

contains() 为集合中的每个实例调用 equals() 方法,以便根据 equals-contract 找出两个实例是否相等。

于 2012-09-12T14:23:45.463 回答