Java集合中更好的类型安全性

时间:2010-03-25 13:55:45

标签: java collections type-safety

在我的java编码中,我经常会遇到几个Map<String,Map<String,foo>>Map<String,List<String>>,然后我无法记住哪个String是哪个键。我使用//Map<capabiltyId,Map<groupId,foo>>//Map<groupId,List<capabilityId>对声明发表评论,但这不是最好的解决方案。如果String不是最终的,我会创建新的类CapabilityId extends StringGroupId extends String,但我不能。有没有更好的方法来跟踪哪个是关键,可能让编译器强制执行它?

7 个答案:

答案 0 :(得分:9)

如果需要,请在包装类中包装字符串:

class GroupId implements Comparable {
   private String groupId;

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

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

答案 1 :(得分:7)

CapabilityId可以包含名为“id”的String字段,而不是CapabilityId扩展String。然后,您的Map可以定义为Map<CapabilityId, Map<GroupId, Foo>>,您可以通过关键类的getId()获取各个ID字段。

我不确定自己会这样做,但如果我这样做,这可能就是我要做的。

您可以通过使用带有ID字段和abstract GenericId方法的getId()类来限制混乱,并让CapabilityIdGroupId继承。

答案 2 :(得分:3)

创建一个ID类,您可以将其子类化,该类包含String字段以及使用该字段的equals()hashCode()的实现。

答案 3 :(得分: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..
}

通过这种方式,您可以在方法/参数名称中看到它所期望/返回的内容。

答案 4 :(得分:1)

有很多方法可以解决这个问题(一些已经提到过):

  • 作为@Roman,将通用类型包装在更具体的类型中,从而提供更强的类型。打字很好,IMO。
  • 作为@nanda,请使用更具体的集合类型。 Java库在这方面有点差。这取决于你对依赖关系的看法。
  • 作为@BalusC,将所有蠢事都移到一个icky类。并没有真正解决问题,但它确实包含它(如在Ghostbusters中)。
  • Map<String,Map<String,foo>>看起来非常像你有一个复合键,即一个由两部分组成的键。因此,引入一个不可变的复合键类,它是一个表示两个组件值对象的值对象。

答案 5 :(得分:0)

而不是Map<String,List<String>>您应该使用Google Guava / Google Collection中的Multimap

http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/collect/Multimap.html

答案 6 :(得分:0)

添加其他答案:

包裹它。

这不仅仅是解决问题的方法,而是一般的好主意,即避免简单 参数。您的代码将获得可读性,理智性和可维护性。 你可以添加各种不错的属性,例如声明它@Immutable。当你发现这种方式时,记住和控制会更好。你拥有这门课程,可以随心所欲地做任何事情。