2010-03-25 54 views
5

在我的java編碼中,我經常會得到幾個Map<String,Map<String,foo>>Map<String,List<String>>,然後我無法記住哪個String是哪個鍵。我以//Map<capabiltyId,Map<groupId,foo>>//Map<groupId,List<capabilityId>對聲明發表評論,但這不是最好的解決方案。如果字符串不是最終的,我會創建新的類CapabilityId extends StringGroupId extends String,但我不能。有沒有更好的方法來跟蹤哪些是關鍵,並且可能讓編譯器執行它?Java集合中更好的類型安全

+0

你可以使用枚舉而不是字符串?當你有明確定義的密鑰時,這會很有用。 – Carl 2010-03-25 15:16:02

回答

7

代替具有CapabilityId延伸StringCapabilityId可以包括稱爲「id」的String字段;那麼您的Map可以定義爲Map<CapabilityId, Map<GroupId, Foo>>,並且您可以通過關鍵類上的getId()獲得個人ID字段。

我不確定我自己會這樣做,但如果我這樣做,這可能是我會做的。

您可以通過使用帶有id字段的abstract GenericId類和getId()方法來限制混亂,並且CapabilityIdGroupId從它繼承。

+0

這是一個非常林肯式的評論。 – 2010-03-25 14:09:02

+0

我承認我是爲Jerry Pournelle「如果你需要這個,你需要它不好」,但是相反。 – 2010-03-25 17:05:29

+0

這正是我昨天爲了追查內存泄漏而做的事情;而不是150米的字符串對象,我可以通過查看創建了多少個nnnnKey對象,立即發現哪些地圖未被清除。 – rhu 2010-03-25 21:52:18

9

在包裝類裹串,如果你想:

class GroupId implements Comparable { 
    private String groupId; 

    public GroupId (String groupId) { 
     this.groupId = groupId; 
    } 
    ... 
} 

Map<GroupId, List<CapabilityId>> m = ... 
+0

爲什麼要實現Comparable? – 2010-03-25 19:27:40

3

創建ID類,你也可以繼承,以及由String場和equals()hashCode()其使用領域實現的。

0

添加到其他答案:

包裹。

這不僅僅是解決您的問題,而是一個好主意,即避免簡單的 參數。您的代碼將獲得可讀性,完整性和可維護性。 你可以添加各種漂亮的屬性,例如宣佈@Immutable。當你發現這種方式更好記住和控制。你擁有這個班級,可以隨心所欲地做任何事情。

2

我會把它放在單個類中,並利用合理的字段/方法/參數名稱。

public class GroupCapabilities { 
    private Map<String, Map<String, Group>> groupCapabilities; 

    public void addGroup(String capabilityId, Group group) { 
     Map<String, Group> groups = groupCapabilities.get(capabilityId); 
     if (groups = null) { 
      groups = new HashMap<String, Group>(); 
      groupCapabilities.put(capabilityId, group); 
     } 
     groups.put(group.getId(), group); 
    } 

    public Map<String, Group> getGroups(String capabilityId) { 
     return groupCapabilities.get(capabilityId); 
    } 

    public Group getGroup(String capabilityId, String groupId) { 
     Map<String, Group> groups = groupCapabilities.get(capabilityId); 
     return (groups != null) ? groups.get(groupId) : null; 
    } 

    // Etc.. 
} 

這樣,您可以在方法/參數名稱中看到它期望/返回的內容。

1

有多種方式去在這一個(一些已經提到):

  • 作爲@Roman,包裹通用型的更具體的類型,這給了更強的類型。強打字好,國際海事組織。
  • 作爲@nanda,使用更具體的集合類型。 Java庫在這方面有點差。這取決於您對依賴關係的感受。
  • 作爲@BalusC,將所有噁心的東西轉移到惡類中。並沒有真正消除這個問題,但它確實包含了它(就像在Ghostbusters中一樣)。
  • Map<String,Map<String,foo>>看起來非常像你有一個組合鍵,即由兩部分組成的鍵。因此,引入一個不可變的組合鍵類,即一個表示兩個組件值對象的值對象。