ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] 为类实现自定义相等行为可能很棘手。用户对对象需要匹配的等式如何工作有很深的直觉,而像哈希表这样的集合类型有一些微妙的约定,他们希望元素遵循这些约定。 ## 如果您重写==,请重写hashCode。 默认的哈希代码实现提供了一个标识哈希——如果两个对象是完全相同的对象,通常只有相同的哈希代码。同样,==的默认行为是identity。 如果你重写==,这意味着你可能有不同的对象被你的类认为是“相等的”。任何两个相等的对象都必须具有相同的哈希代码。否则,映射和其他基于散列的集合将无法识别这两个对象是等价的。 ## 一定要让你的==运算符遵守等式的数学规则。 一个等价关系应该是: * 条件反射:a == a应该总是返回true。 * 对称的:a == b应该返回与b == a相同的东西。 * 传递式:如果a == b和b == c都返回true,那么a == c也应该返回true。 使用==的用户和代码期望遵循所有这些规则。如果您的类不能遵守这些规则,那么==就不是您要表示的操作的正确名称。 ## 避免为可变类定义自定义等式。 在定义==时,还必须定义hashCode。这两个都应该考虑到对象的字段。如果这些字段改变了,那么就意味着对象的哈希代码可以改变。 大多数基于哈希的集合都没有预料到这一点——它们假设一个对象的哈希代码将永远是相同的,如果这不是真的,那么它的行为可能是不可预测的。 ## 不要在自定义 ==运算符中检查null。 该语言指定此检查是自动完成的,只有当右侧不为空时才调用您的==方法。 ~~~ class Person { final String name; // ··· operator ==(other) => other is Person && name == other.name; int get hashCode => name.hashCode; } ~~~ ~~~ 【bad】 class Person { final String name; // ··· operator ==(other) => other != null && ... } ~~~