Pergunta

Na minha codificação Java, muitas vezes acabo com vários Map<String,Map<String,foo>> ou Map<String,List<String>> E então tenho problemas para lembrar qual string é qual chave. Eu comento a declaração com //Map<capabiltyId,Map<groupId,foo>> ou //Map<groupId,List<capabilityId>, mas não é a melhor solução. Se String não fosse final, eu faria novas aulas CapabilityId extends String e GroupId extends String, mas eu não posso. Existe uma maneira melhor de acompanhar qual coisa é a chave e talvez fazer com que o compilador a aplique?

Foi útil?

Solução

Em vez de ter CapabilityId ampliar String, CapabilityId poderia incluir um String campo chamado "id"; então você Map poderia ser definido como Map<CapabilityId, Map<GroupId, Foo>>, e você pode chegar aos campos de identificação individuais através de um getId() nas suas principais classes.

Não tenho certeza se faria isso sozinho, mas se o fizesse, é provavelmente isso que eu faria.

Você pode limitar a desordem por ter um abstract GenericId classe com um campo de identificação e getId() método, e tem CapabilityId e GroupId herdar dele.

Outras dicas

Enrole as cordas em classes de invólucro, se você quiser:

class GroupId implements Comparable {
   private String groupId;

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

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

Criar um ID classe que você pode subclasse e que consiste em um String campo e implementações de equals() e hashCode() que usam esse campo.

Eu colocaria tudo em classe única e utilizava nomes sensatos de campo/método/argumento.

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

Dessa forma, você pode ver no método/argumento nomes o que ele espera/retorna.

Existem várias maneiras de seguir este (algumas já mencionadas):

  • Como @Roman, embrulhe o tipo de propósito geral em um tipo mais específico, que fornece uma digitação mais forte. Digitação forte boa, IMO.
  • Como @Nanda, use um tipo de coleção mais específico. A biblioteca Java é um pouco pobre nesta área. Depende de como você se sente sobre as dependências.
  • Como @balusc, mova todas as coisas nojentas para uma aula nojenta. Realmente não remove o problema, mas ele o contém (como em Ghostbusters).
  • Map<String,Map<String,foo>> Parece que você tem uma chave composta, ou seja, uma chave que compreende duas partes. Portanto, introduza uma classe de chave composta imutável, que é um objeto de valor que representa os dois objetos de valor de componentes.

Ao invés de Map<String,List<String>> Você deve usar o MultiMAP do Google Guava / Google Collection

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

Adicionando às outras respostas:

Enrole -o.

Não é apenas uma solução para o seu problema, mas uma boa ideia em geral, ou seja, evite parâmetros simples. Seu código ganhará legibilidade, sanidade e manutenção. Você pode adicionar todos os tipos de propriedades agradáveis, por exemplo, declarar @imutable. Como você descobriu, é melhor lembrar e controlar. Você possui a classe e pode fazer o que quiser com ela.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top