2012-09-26 110 views
1

我正在考慮在Java中使用BusinessObjects的Set。我的意圖是,在每個集合中應該只有每個業務對象的一個​​實例,但是一個業務對象可以在多個集合中共享。所以,作爲一個例子:Java - equals和hashcode

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

你是否真的希望只有在他們的課程基礎上,這些對象纔是平等的?否則,向類中添加一個屬性,比如「type」的實例變量可能更有意義。 – shortstuffsushi

回答

4

爲什麼不簡單地使用枚舉? 您可以使用業務對象的Enum和Business Objects的EnumSet

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契約。

對於業務對象的一般規則是等於,並且需要使用業務對象PK實現哈希碼。

Like For Employee對象員工編號可視爲業務密鑰,而pk可以不同,所以equals和hashcode應基於員工編號。

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),這會在各種集合中使用它。

如果您需要控制程序中實例化的特定類型實例的數量,那麼只需實例化該對象的一個​​實例即可。

2

將所有業務對象放入HashSet中。在HashSet中不能有重複項(通過equals方法),因此如果將B1,B11和B2放入HashSet中,它將包含B1和B2。

您應該重寫BusinessObject中的equals和hashCode方法,以處理使BusinessObject唯一的那些屬性。

0

如果由於某些原因您無法遵循AmitD的建議並使用Enums,那麼您可以使用標記界面上的地圖來代替Sets。

我不知道是什麼問題,這將是解決,但......

  1. 創建一個新的標記接口
  2. 讓每個業務對象類的實現它
  3. 在每個地方你想爲你描述它的集合,使用

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

這很奇怪;我確信。