为什么 Java 中没有 "Equalable" 接口?

3

Objectequals 方法只比较地址:

public boolean equals(Object obj) {  
    return (this == obj);  
}

我认为在大多数情况下它并没有用处,因此我们可以重写它。但是对于我编写的大多数类,我没有重写equals方法,因为我根本不会使用它...

所以我想知道,为什么Java语言设计者将equals方法放在了Object中? 为什么没有像Comparable一样有一个"Equalable"接口呢?


即使对于没有覆盖重写的对象,知道一个对象始终等于自身也是非常有用的。 - chrylis -cautiouslyoptimistic-
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - khelwood
两个事物要么相等,要么不相等。它们可能无法比较,但这意味着它们不相等。 - Ankit
“因为我根本不会使用它” - 你的代码中没有使用任何集合吗? - user11153
3个回答

4
equals()方法被Java系统类使用,例如在HashMap中。由于每个对象都可能存储在HashMap中,因此每个对象都需要一个equals()方法。对于此目的,默认实现足够使用。
这只是一个例子,equals()被调用的地方有很多。

2
每个对象也可以放置在TreeMap中 - 但是,如果它不是“可比较的”(并且将引发异常)Set<Object> s = new TreeSet<>(); s.add(new Object());将编译得很好。 - amit
在TreeMap出现之前的多年前,每个对象都有一个equals()和hashCode()方法是一项设计决策。 - Thomas Stets
1
@amit HashMap和Lists比TreeMaps更常用。equals也有一个合理的默认实现,而compare没有。为几乎每个类添加样板默认的equals方法或为第三方类创建包装器将非常不方便。 - kapex
@kapep 我批评了“由于每个对象都可以存储在HashMap中,因此每个对象都需要一个equals()方法”的论点。模板代码是一个不同的论点,而“您需要支持所有对象,因为每个对象都可以插入”是另一个论点,而且反例是Comparable。 - amit
@amit 好的,我误解了。TreeSet只接受所有对象,因为您还可以提供比较器使其适用于非可比较对象。基于“equals”的集合也可以通过提供(默认)“相等比较器”来实现相同的功能(不确定如何命名)。但我认为,在同一集合类型中混合比较器和可比较方法是不好的设计。 - kapex

4

身份提供了平等的普遍定义。每个对象都等于它自己。它可能或可能不与一些不是它自己的对象在逻辑上相等。如果是这样,请重写equalshashCode。如果不是,请继承Object的方法。

这与可比性非常不同。一个由类表示的结构可能缺乏任何有意义的总序 - 考虑复数。


1
如果Java有类似于“Comparable”接口的“Equalable”接口,就不需要在每个对象中都包含它,因此在将对象添加到集合等操作时可能会出现新问题。
当然,“hashcode + equals”契约范例也会被破坏。
请查看《Effective Java》中的此链接。

http://www.ideyatech.com/2011/04/effective-java-equals-and-hashcode/


同样的情况也适用于可比较对象。Set<Object> s = new TreeSet<>(); s.add(new Object()); 虽然可以编译通过,但会抛出异常。 - amit
@amit 但是这样的话,您将不得不在创建每个集合时使用自定义的“等值器”。 - user11153

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接