我正在考虑在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;
}
}
你认为这是个好主意吗?
答案 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的建议并使用枚举,那么你可以使用在标记界面上键入的地图代替套装。
我不知道这会解决什么问题,但是......
在您想要收集的每个地方,请使用
Map<Class<? extends Marker>, Marker> soloBOMap = // whatever concrete map;
soloBOMap.put(bo.getClass(), bo);
这很奇怪;我确定。