实现哈希码和等于

时间:2019-04-05 21:22:54

标签: 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>
    }
} 

客户端填充CompositeWork这样的内容

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"));
    }
}

要在childWork的{​​{1}}中的CompositeWork中强制执行HashSet<>()hashcode()的{​​{1}}的唯一性?

工作界面中会出现这种情况吗?
CompositeWork类?
还是在EasyWork和HardWork中实现?

3 个答案:

答案 0 :(得分:1)

由于需要区分EasyWorkHardWork,因此需要在这些类中实现这些方法。

关于此主题,article很不错。

答案 1 :(得分:1)

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

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

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

  • 另一方面,如果您希望HardWork个对象具有相同的id是相等的,则需要覆盖equals()hashCode()HardWork中。如果没有,请不要打扰。

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

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

答案 2 :(得分:1)

我看到了John Kugelman的答案,我几乎同意了。几乎-因为有一件非常重要的事情经常被人们遗忘。如果要在像EasyWork这样的哈希相关集合中使用HardWorkHashSet对象,除了覆盖equalshashcode之外,还必须创建类一成不变的。意思是,

  1. 两个课程都必须是final
  2. 您的equalshashcode方法要使用的
  3. 字段必须是最终字段。

说明

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