如何遵循自反性、对称性、传递性改写equals方法以维护集合正确性?

2026-04-30 16:530阅读0评论SEO基础
  • 内容介绍
  • 相关推荐

本文共计1089个文字,预计阅读时间需要5分钟。

如何遵循自反性、对称性、传递性改写equals方法以维护集合正确性?

集合类(例如 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 查不到

HashMapget() 时会先用 key 的 hashCode() 定位桶,再用 equals() 确认是否命中。

阅读全文

本文共计1089个文字,预计阅读时间需要5分钟。

如何遵循自反性、对称性、传递性改写equals方法以维护集合正确性?

集合类(例如 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 查不到

HashMapget() 时会先用 key 的 hashCode() 定位桶,再用 equals() 确认是否命中。

阅读全文