繁体   English   中英

Java-等于和哈希码

[英]Java - equals and hashcode

我正在考虑在Java中使用一Set BusinessObjects。 我的意图是,每个集合中每个业务对象应该只有一个实例,但是一个业务对象可以在许多集合中共享。 因此,例如:

BO1 - instance of BusinessObject1
BO11 - instance of BusinessObject1
BO2 - instance of BusinessObject2

这是对的

[BO1,BO2]或[BO1]

但这不是[BO1,BO11]

由于我想确保这是强制性的,因此我在考虑指定这样的AbstractBusinessObject:

public abstract class AbstractBusinessObject {

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

    @Override
    public boolean equals(Object obj) {
        if (obj != null)
            return this.getClass() == obj.getClass();
        return false;
    }
}

您认为这是个好主意吗?

为什么不简单地使用Enums? 您可以使用业务对象的Enum和业务对象的EnumSet

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY;
    static final EnumSet<Day> weekend = EnumSet.of(SATURDAY,SUNDAY);
}

教程在这里

现在,如果您的业务对象不是为上述目的而设计的,则只需以常规方式实现equals和hashcode。 HashSet的add方法将始终忽略重复项。

链接讨论了关于等号和哈希码契约。

对于业务对象,一般规则是相等的,并且需要使用您的业务对象PK来实现哈希码。

像For Employee对象一样,可以将员工编号视为业务密钥,而pk可以不同,因此等于和哈希码应基于员工编号。

不,这是一个坏主意。 这实际上并不能阻止代码的不同部分执行

BusinessObject bo1 = new BusinessObject();
bo1.setId(1);
bo1.setName("foo");

BusinessObject bo1copy = new BusinessObject();
bo1copy.setId(1);
bo1copy.setName("bar");

因此,具有不同字段值的同一“业务对象”的两个副本。

您的equals()实现还会将BusinessObject所有实例都视为具有相同的值(以上代码中的bo1.equals(bo1copy) == true ),这将在任何类型的集合中使用它。

如果您需要控制程序中实例化的某种类型的实例的数量,则只需实例化该对象的一个​​实例即可。

将所有业务对象都放入HashSet中。 HashSet中不能有重复项(通过equals方法),因此,如果将B1,B11和B2放入HashSet中,它将包含B1和B2。

您应该重写BusinessObject中的equals和hashCode方法,以使用那些使BusinessObject唯一的属性。

如果由于某种原因您不能遵循AmitD的建议而使用枚举,则可以使用在标记界面上键入键的Maps来代替Sets。

我不知道这将解决什么问题,但是...

  1. 创建一个新的Marker界面
  2. 让您的每个业务对象类都实现它
  3. 在您想要收集的每个地方,使用

     Map<Class<? extends Marker>, Marker> soloBOMap = // whatever concrete map; soloBOMap.put(bo.getClass(), bo); 

有点奇怪; 我敢肯定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM