Java:使用 toString().equals() 与 equals()
Java: Use toString().equals() vs. equals()
这是一个理论问题。我有一个自己设计的对象,其中包含一堆变量、方法等。我覆盖了 toString 方法,主要用于记录目的,将变量的值设为 return。在我看来,比较此对象的实例的最简单和最直接的方法是比较从 toString 方法获得 returned 的内容。例如,equals 方法可能看起来像
public boolean equals(MyObject instance)
{
return toString().equals(instance.toString());
}
有什么理由不这样做吗?
避免这种模式的一个原因是速度:为了使用 toString()
比较相等性,您必须这样做:
- 为对象
this
创建临时String
对象
- 为对象
instance
创建临时String
对象
- 比较第一个
String
和第二个 String
个字符
- 使临时字符串可用于垃圾检测
如果直接进行比较,则可以跳过大部分内容。例如,直接比较 int
s 需要比较 4 个字节,而比较它们的字符串表示最多需要 9 个字节的比较。其他数据类型也会出现类似情况。
dasblinkenlight 简要总结了性能原因导致您无法执行您要求的操作。
避免这种模式的另一个重要原因与 toString()
方法的一般契约有关。 class 对象的所有可覆盖方法都有一个 通用契约 。因为这些方法由您在 Java 中定义的每个 class 继承,并且因为它们在许多自定义 class 中经常被覆盖,所以了解并遵守它们的一般契约非常重要。
toString()
的一般契约是对象方法中最简单的:
Returns a string representation of the object. In general, the
toString method returns a string that "textually represents" this
object. The result should be a concise but informative representation
that is easy for a person to read. It is recommended that all
subclasses override this method.
没有要求 toString() 返回的字符串符合特定格式,也没有要求您必须指定作为 API.[=22 的一部分返回的字符串的格式=]
正因为如此,toString() 返回的对象的字符串表示最常见的是 实现细节,它可以从您的 class到下一个。如果您基于它们进行相等比较,更改 toString()
返回的字符串表示可能会导致程序失败。
不基于 toString()
方法进行相等比较的另一个原因是这样做不会为您的 class 提供所需的基础结构,因此它可以与 Java 一起使用集合框架。 Java 集合 classes 需要格式正确的 equals()
和 hashCode()
方法来存储其中的对象才能正常工作:
如果您正在编写的 class 有任何机会用于任何 Java 集合框架 classes and/or它可能被其他程序员使用,编写格式良好的 equals()
和 hashCode()
方法是值得的。
因为任何格式合理的 equals()
方法的性能都将超过基于 toString()
的字符串比较的性能......并且由于许多 classes 无论如何都应该有一个格式正确的 equals() 方法......你也可以继续使用自定义 equals()
方法。
这是一个理论问题。我有一个自己设计的对象,其中包含一堆变量、方法等。我覆盖了 toString 方法,主要用于记录目的,将变量的值设为 return。在我看来,比较此对象的实例的最简单和最直接的方法是比较从 toString 方法获得 returned 的内容。例如,equals 方法可能看起来像
public boolean equals(MyObject instance)
{
return toString().equals(instance.toString());
}
有什么理由不这样做吗?
避免这种模式的一个原因是速度:为了使用 toString()
比较相等性,您必须这样做:
- 为对象
this
创建临时 - 为对象
instance
创建临时 - 比较第一个
String
和第二个String
个字符 - 使临时字符串可用于垃圾检测
String
对象
String
对象
如果直接进行比较,则可以跳过大部分内容。例如,直接比较 int
s 需要比较 4 个字节,而比较它们的字符串表示最多需要 9 个字节的比较。其他数据类型也会出现类似情况。
dasblinkenlight 简要总结了性能原因导致您无法执行您要求的操作。
避免这种模式的另一个重要原因与 toString()
方法的一般契约有关。 class 对象的所有可覆盖方法都有一个 通用契约 。因为这些方法由您在 Java 中定义的每个 class 继承,并且因为它们在许多自定义 class 中经常被覆盖,所以了解并遵守它们的一般契约非常重要。
toString()
的一般契约是对象方法中最简单的:
Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.
没有要求 toString() 返回的字符串符合特定格式,也没有要求您必须指定作为 API.[=22 的一部分返回的字符串的格式=]
正因为如此,toString() 返回的对象的字符串表示最常见的是 实现细节,它可以从您的 class到下一个。如果您基于它们进行相等比较,更改 toString()
返回的字符串表示可能会导致程序失败。
不基于 toString()
方法进行相等比较的另一个原因是这样做不会为您的 class 提供所需的基础结构,因此它可以与 Java 一起使用集合框架。 Java 集合 classes 需要格式正确的 equals()
和 hashCode()
方法来存储其中的对象才能正常工作:
如果您正在编写的 class 有任何机会用于任何 Java 集合框架 classes and/or它可能被其他程序员使用,编写格式良好的
equals()
和hashCode()
方法是值得的。因为任何格式合理的
equals()
方法的性能都将超过基于toString()
的字符串比较的性能......并且由于许多 classes 无论如何都应该有一个格式正确的 equals() 方法......你也可以继续使用自定义equals()
方法。