2010-03-25 27 views
5

En mi codificación java, a menudo termino con varios Map<String,Map<String,foo>> o Map<String,List<String>> y luego me cuesta recordar qué cadena es qué tecla. Comenta la declaración con //Map<capabiltyId,Map<groupId,foo>> o //Map<groupId,List<capabilityId>, pero no es la mejor solución. Si String no fuera final, haría nuevas clases CapabilityId extends String y GroupId extends String, pero no puedo. ¿Hay una mejor manera de hacer un seguimiento de qué cosa es la clave y tal vez hacer que el compilador lo haga cumplir?Mejor tipo de seguridad en colecciones Java

+0

¿Podría usar una enumeración en lugar de una cadena? Eso puede ser útil cuando tienes claves bien definidas. – Carl

Respuesta

7

En lugar de tener CapabilityId se extienden String, CapabilityId podría incluir un campo de String llamado "id"; entonces su Map podría definirse como Map<CapabilityId, Map<GroupId, Foo>>, y podría obtener los campos de ID individuales a través de getId() en sus clases de clave.

No estoy seguro de que haría esto yo mismo, pero si lo hiciera, esto es probablemente lo que haría.

podría limitar el desorden por tener una clase abstract GenericId con un campo id y getId() método, y tienen CapabilityId y GroupId hereda de ella.

+0

Ese es un comentario muy Lincoln-esque. –

+0

Admito que iba por el Jerry Pournelle "Si necesitas esto, lo necesitas mal", pero a la inversa. –

+0

Esto es exactamente lo que hice ayer para rastrear una fuga de memoria; en lugar de los objetos String de 150m, pude detectar instantáneamente qué mapa no se estaba eliminando al ver cuántos objetos nnnnKey se estaban creando. – rhu

9

cadenas Envuelva envoltura clases si quieren:

class GroupId implements Comparable { 
    private String groupId; 

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

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

¿Por qué implementar Comparable? –

3

crear una clase ID que puede subclase, y que consiste en un campo String y las implementaciones de equals() y hashCode() que utilizan ese campo.

0

Agregando a las otras respuestas:

envolverlo.

No es solo una solución a su problema sino una buena idea en general, es decir, evitar los parámetros simples de . Su código obtendrá legibilidad, cordura y facilidad de mantenimiento. Puede agregarle todo tipo de propiedades agradables, p. Ej. declararlo @Imutable. Como lo descubrió de esta manera, es mejor recordar y controlar. Eres propietario de la clase y puedes hacer lo que quieras con ella.

2

Lo pondría todo en una sola clase y haría uso de los nombres 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.. 
} 

De esta manera, puede ver en los nombres método/argumento lo que espera/devuelve.

1

Hay un número de maneras de ir sobre este (algunos ya mencionado):

  • Como @Roman, envuelva el tipo de propósito general en un tipo más específico, lo que da a escribir más fuerte. Fuerte tipeo bueno, IMO.
  • Como @nanda, use un tipo de colección más específico. La biblioteca de Java es un poco pobre en esta área. Depende de cómo te sientas con respecto a las dependencias.
  • Como @BalusC, mueve todo lo repulsivo a una clase asquerosa. Realmente no elimina el problema, pero sí lo contiene (como en Cazafantasmas).
  • Map<String,Map<String,foo>> se parece mucho a que tiene una clave compuesta, es decir, una clave que consta de dos partes. Por lo tanto, introduzca una clase de clave compuesta inmutable, es decir, un objeto de valor que represente los objetos de valor de dos componentes.
Cuestiones relacionadas