2014-02-24 162 views
6

假设我有一个类,所有实例都被认为是相等的。一个典型的用例是没有任何状态的类,但只作为函数。所有实例相同的类的HashCode实现

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之类的微不足道的值,则可能导致与其他类似的类的冲突。

所以它似乎归结为这样一个问题:如何实现一个哈希码可能是唯一的给定类,但其所有实例相同。

我想出了这两个想法。你觉得呢,他们理智吗?

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

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

基于类的方法对我来说看起来很好......但是如果我可能会问,你需要什么equals/hashCode呢? – fge

+0

我认为当他们没有状态只是函数时,你不需要把对象放入一个集合中。 – gyorgyabraham

+0

我没有具体的用例,但我想你可能想要对一些数据应用一组操作。例如,JDK Comparator在其接口中定义了equals:http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html – Natix

回答

6

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

1

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

尽管没有提供更多的上下文,但您试图做的事情并没有真正产生大量的意义。如果这些对象是无状态的,那么就让它们成为一个单例(如果你确实需要一个实例,例如将它们用作策略模式中的策略),或者如果不需要实例,则使所有方法都是静态的。我猜如果他们是所有实现相同的接口,然后能够比较它们的策略是有道理的,但如果每个实现是一个单身人士然后默认的方法将做你需要的一切。

+0

_...如果每个实现都是单例,那么默认的Object equals和hashCode方法会做你需要的一切。 – Natix