【问题标题】:HashCode implementation for class whose all instances are equal所有实例都相等的类的 HashCode 实现
【发布时间】:2014-03-25 23:19:46
【问题描述】:

假设我有一个类,其中所有实例都被认为是相等的。一个典型的用例是用于没有任何状态但仅表现为函数的类。

public class ToStringFunction implements Function<Object, String> {

    @Override
    public String apply(Object o) {
        return o.toString();
    }

    @Override
    public boolean equals(Object o) {
        return o instanceof ToStringFunction;
    }
}

现在,应该如何实现 hashCode 方法?自然,它需要是一个常数值才能遵守 equals/hashCode 合约。但这应该是什么价值?如果使用了一些微不足道的值,例如 0 或 1,则可能会导致与其他类似的类发生冲突。

所以这似乎归结为一个问题:如何实现一个 hashCode,它对于给定的类可能是唯一的,但对于它的所有实例都是相同的

我想出了这两个想法。你怎么看,他们是理智的吗?

@Override
public int hashCode() {
    return ToStringFunction.class.hashCode();
}

@Override
public int hashCode() {
    return "ToStringFunction".hashCode();
}

【问题讨论】:

  • 基于类的方法对我来说看起来不错...但是如果我可以问,您需要 equals/hashCode 做什么?
  • 我认为当对象没有状态只是函数时,您不需要将它们放入集合中。
  • 我没有具体的用例,但我想您可能想要一组要应用于某些数据的操作。例如,JDK Comparator 在其接口中定义了 equals:docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

标签: java hashcode equality


【解决方案1】:

如果一个类没有状态,它应该是一个单例、一个抽象类或静态方法的存储库(如数学)。因此,为它重写 equals 和 hashcode 是没有意义的。

【讨论】:

    【解决方案2】:

    您可以只使用串行版本 ID(将其转换为整数)。这将是每个班级的唯一编号。

    尽管没有提供更多上下文,但您尝试做的事情并没有多大意义。如果这些对象是无状态的,那么只需将它们设为单例(如果您确实需要一个实例,例如将它们用作策略模式中的策略),或者如果您不需要实例,则将所有方法设为静态。

    我猜如果它们都是实现相同接口的策略,那么能够比较它们是有意义的,但如果每个实现都是单例,那么默认的 Object equalshashCode 方法将满足您的所有需求.

    【讨论】:

    • ...如果每个实现都是单例,那么默认的 Object equals 和 hashCode 方法将满足您的所有需求。 好点。
    【解决方案3】:

    我认为我有一个“合法的”(至少对我来说!:-P)用例:我有一个层次结构的类,其中一些子类有状态,而另一些则没有。无论如何,我想使用Map&lt;BaseClass,Value&gt; 并使用ChildClassWihtoutState extends BaseClass 的所有实例作为地图的唯一键,而不添加特殊的getInstance()

    那么,如何使用限定类名字符串的哈希值呢?它在 jvm 中应该是唯一的,对吧?

    public int hashCode() {
       return getClass().getName().hashCode();
    }
    

    【讨论】:

      猜你喜欢
      • 2019-04-08
      • 2016-08-22
      • 2021-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      • 2022-01-25
      相关资源
      最近更新 更多