Лучшая безопасность типов в коллекциях Java - PullRequest
5 голосов
/ 25 марта 2010

В моем Java-кодировании я часто получаю несколько Map<String,Map<String,foo>> или Map<String,List<String>>, а затем мне трудно вспомнить, какая строка является какой, какой ключ.Я комментирую декларацию с //Map<capabiltyId,Map<groupId,foo>> или //Map<groupId,List<capabilityId>, но это не самое лучшее решение.Если бы String не был окончательным, я бы делал новые классы CapabilityId extends String и GroupId extends String, но я не могу.Есть ли лучший способ отследить, какая вещь является ключевой, и, возможно, компилятор принудительно ее задействует?

Ответы [ 7 ]

9 голосов
/ 25 марта 2010

Оберните строки в классы-обёртки, если хотите:

class GroupId implements Comparable {
   private String groupId;

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

Map<GroupId, List<CapabilityId>> m = ...
7 голосов
/ 25 марта 2010

Вместо CapabilityId extension String, CapabilityId может включать поле String с именем "id"; тогда ваш Map может быть определен как Map<CapabilityId, Map<GroupId, Foo>>, и вы можете получить доступ к отдельным полям идентификатора через getId() в ваших ключевых классах.

Я не уверен, что сделал бы это сам, но если бы я сделал, это, вероятно, то, что я бы сделал.

Вы можете ограничить беспорядок, имея класс abstract GenericId с полем id и методом getId(), и CapabilityId и GroupId наследуют его.

3 голосов
/ 25 марта 2010

Создайте класс ID, который вы можете подклассить и который состоит из поля String и реализаций equals() и hashCode(), которые используют это поле.

2 голосов
/ 25 марта 2010

Я бы поместил все это в один класс и использовал бы разумные имена полей / методов / аргументов.

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 голос
/ 25 марта 2010

Есть несколько способов пойти по этому (некоторые уже упоминались):

  • Как @Roman, оберните тип общего назначения в более конкретный тип, который дает более сильную типизацию. Сильная типизация хорошо, ИМО.
  • В качестве @nanda используйте более конкретный тип коллекции. Библиотека Java немного бедна в этой области. Это зависит от того, как вы относитесь к зависимостям.
  • Как @BalusC, переместите все непристойные вещи в неприличный класс. На самом деле не устраняет проблему, но она содержит ее (как в Ghostbusters).
  • Map<String,Map<String,foo>> очень похоже на то, что у вас есть составной ключ, то есть ключ, который состоит из двух частей. Итак, представьте класс неизменяемого составного ключа, который является объектом значения, представляющим два объекта значения компонента.
0 голосов
/ 25 марта 2010

Добавление к другим ответам:

Заверни это.

Это не просто решение вашей проблемы, но и хорошая идея в целом, то есть избегайте простого параметры. Ваш код приобретет читабельность, здравомыслие и ремонтопригодность. Вы можете добавить все виды хороших свойств, например, объявить это @Imutable. Как вы выяснили, этот путь лучше запомнить и контролировать. Вы являетесь владельцем класса и можете делать с ним все, что захотите.

0 голосов
/ 25 марта 2010

Вместо Map<String,List<String>> вы должны использовать Multimap из Google Guava / Google Collection

http://google -collections.googlecode.com / SVN / багажник / Javadoc / index.html? COM / Google / общие / собирать / Multimap.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...