实现哈希码和平等的责任

  • 本文关键字:责任 哈希码 实现 java
  • 更新时间 :
  • 英文 :


我有一个名为 Work 的接口

public class interface Work {
boolean completeWork(Job j);
}

然后我有一个复合类

public class CompositeWork implements Work {
private Set<Work> childWork = new HashSet<>();
public boolean completeWork(Job j) {
return childWork.stream().allMatch(w -> w.completeWork(j));
}
public void addWork(Work w) {
childWork.add(w);
}
}

我有不同的工作类型如下:

public class EasyWork implements Work {
public boolean completeWork(Job j) {
<do some work>
}
} 
public class HardWork implements Work {
private String id;
public Hardwork(String id) {
this.id = id;
}
public boolean completeWork(Job j) {
<do some work>
}
} 

客户端填充复合工作类似这样的东西

public class Client {
public static void main(String[] args) {
CompositeWork workHolder = new CompositeWork();
workHolder.add(new EasyWork());
workHolder.add(new EasyWork());
workHolder.add(new HardWork("1"));
workHolder.add(new HardWork("2"));
}
}

为了在HashSet<>()CompositeWork中强制执行childWork的唯一性,我在哪里实现hashcode()equals()

这是否发生在工作界面中?
复合作业类?
还是在EasyWork和HardWork中实现?

我们无法为您回答这个问题。这取决于您希望类的行为方式。

任何类的默认行为是不同的实例将相互比较不相等。如果您同意所有EasyWork对象都是不同的,并且所有HardWork对象都是不同的,即使它们包含相同的数据,那么您不需要执行任何操作。默认方法可能就足够了。

否则,您应该根据具体情况检查每个类:

  • 如果您希望HardWork对象相等,如果它们具有相同的id,另一方面,您需要覆盖equals()并在HardWorkhashCode()。如果没有,请不要打扰。

  • 同样,如果EasyWork对象应该彼此相等,那么您也需要在那里覆盖它们。如果没有,请不要打扰。

  • 此外,如果您希望CompositeWork对象彼此相等,如果它们具有相同的子Set,那么您也可以在那里覆盖它们。如果没有,请不要打扰。

因为你需要区分EasyWorkHardWork,所以你需要在这些类中实现这些方法。

这是一篇关于这个主题的好文章。

我看到了约翰·库格尔曼的回答,我几乎同意。几乎 - 因为有一件非常重要的事情经常被遗忘。如果你打算在像HashSet这样的哈希依赖集合中使用EasyWorkHardWork对象,除了覆盖equalshashcode之外,你还必须使你的类不可变。这意味着,

  1. 你的两个类都必须是final
  2. equalshashcode方法将使用的字段必须是最终的。

解释

如果对象不是不可变的,那么您可以更改其某些字段,然后其hashCode将返回新结果,然后由于哈希表中的位置错误,您将无法访问集合中的此对象。

最新更新