如何遵循自反性、对称性、传递性改写equals方法以维护集合正确性?
- 内容介绍
- 相关推荐
本文共计1089个文字,预计阅读时间需要5分钟。
集合类(例如 HashSet、ArrayList)内部使用 equals 方法来判断元素是否存在。如果对象的 equals 方法返回 false,那么即使 list.contains(x) 也可能返回 false。这是因为在集合中,默认的 equals 方法通常不会识别对象为自己,导致即使对象是集合的成员,也可能返回 false。
常见破环自反性的写法:
- 在字段比较前做了非空 trim 或 toLowerCase,但没对当前对象自身做同样处理(比如
this.name.trim().equalsIgnoreCase(other.name.trim()),而this.name本身含首尾空格,this.name.trim()就和原始值不等了) - 用了
instanceof判类型后直接强转,却忘了先检查this == obj
正确做法:开头加 if (this == obj) return true;,这是最廉价也最可靠的自反性保障。
对称性被破坏会让 HashMap 的 key 查不到
HashMap 在 get() 时会先用 key 的 hashCode() 定位桶,再用 equals() 确认是否命中。
本文共计1089个文字,预计阅读时间需要5分钟。
集合类(例如 HashSet、ArrayList)内部使用 equals 方法来判断元素是否存在。如果对象的 equals 方法返回 false,那么即使 list.contains(x) 也可能返回 false。这是因为在集合中,默认的 equals 方法通常不会识别对象为自己,导致即使对象是集合的成员,也可能返回 false。
常见破环自反性的写法:
- 在字段比较前做了非空 trim 或 toLowerCase,但没对当前对象自身做同样处理(比如
this.name.trim().equalsIgnoreCase(other.name.trim()),而this.name本身含首尾空格,this.name.trim()就和原始值不等了) - 用了
instanceof判类型后直接强转,却忘了先检查this == obj
正确做法:开头加 if (this == obj) return true;,这是最廉价也最可靠的自反性保障。
对称性被破坏会让 HashMap 的 key 查不到
HashMap 在 get() 时会先用 key 的 hashCode() 定位桶,再用 equals() 确认是否命中。

