Лучшая безопасность типов в наборах Java

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

5
задан Paul Tomblin 25 March 2010 в 13:55
поделиться

7 ответов

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

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

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

7
ответ дан 18 December 2019 в 07:08
поделиться

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

3
ответ дан 18 December 2019 в 07:08
поделиться

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

  • Как @Roman, оберните тип общего назначения в более конкретный тип, который обеспечивает более надежную типизацию. Сильный набор текста хорош, ИМО.
  • В качестве @nanda используйте более конкретный тип коллекции. Библиотека Java в этой области немного бедна. Это зависит от того, как вы относитесь к зависимостям.
  • Как @BalusC, переместите все неприглядные вещи в неприглядный класс. На самом деле не устраняет проблему, но содержит ее (как в «Охотниках за привидениями»).
  • Map > очень похоже на составной ключ, то есть ключ, состоящий из двух частей. Итак, представьте неизменяемый составной ключевой класс, то есть объект значения, представляющий два объекта значений компонента.
1
ответ дан 18 December 2019 в 07:08
поделиться

Вместо Map> следует использовать Multimap из Google Guava / Google Collection

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

0
ответ дан 18 December 2019 в 07:08
поделиться

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

class GroupId implements Comparable {
   private String groupId;

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

Map<GroupId, List<CapabilityId>> m = ...
9
ответ дан 18 December 2019 в 07:08
поделиться

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

Оберните его.

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

0
ответ дан 18 December 2019 в 07:08
поделиться

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

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..
}

Таким образом, вы можете увидеть в именах метода / аргумента, что он ожидает / возвращает.

2
ответ дан 18 December 2019 в 07:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: