Java - equals和hashcode

时间:2012-09-26 18:19:59

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

你认为这是个好主意吗?

4 个答案:

答案 0 :(得分:4)

为什么不简单地使用枚举? 您可以使用Enum业务对象和EnumSet Business Objects。

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

教程here

现在,如果您的业务对象不是为上述目的而设计的,那么只需以正常方式实现equals和hashcode即可。 无论如何,HashSet add方法都会忽略重复项。

这个link讨论了equals和hashcode合约。

对于Business对象,一般规则是equals,并且需要使用业务对象PK实现hashcode。

Like For Employee对象员工编号可以被视为业务密钥,pk可以不同,因此equals和hashcode应该基于员工编号。

答案 1 :(得分:3)

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

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),这会在任何类型的集合中使用它。 p>

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

答案 2 :(得分:2)

将所有业务对象抛出到HashSet中。您不能在HashSet中使用重复项(通过equals方法),因此如果将B1,B11和B2投入HashSet,它将包含B1和B2。

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

答案 3 :(得分:0)

如果由于某种原因你无法遵循AmitD的建议并使用枚举,那么你可以使用在标记界面上键入的地图代替套装。

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

  1. 创建新的标记界面
  2. 让每个Business Object类实现它
  3. 在您想要收集的每个地方,请使用

    Map<Class<? extends Marker>, Marker> soloBOMap = // whatever concrete map;
    soloBOMap.put(bo.getClass(), bo);
    
  4. 这很奇怪;我确定。