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
Respuesta
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.
Ese es un comentario muy Lincoln-esque. –
Admito que iba por el Jerry Pournelle "Si necesitas esto, lo necesitas mal", pero a la inversa. –
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
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 = ...
¿Por qué implementar Comparable? –
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.
En lugar de Map<String,List<String>>
se debe utilizar Multimapa de Google Guava/Google Colección
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.
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.
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.
- 1. con seguridad de tipos de colecciones/estructuras anidadas en Java
- 2. Seguridad tipo, genéricos Java y consultas
- 3. colecciones java vs mapa en colecciones framework
- 4. Comparación de dos colecciones en Java
- 5. seguridad Tipo: Desactivada fundido
- 6. Java fusionar 2 colecciones en O (1)
- 7. Java problema colecciones covarianza
- 8. Java Collections.checked *() versus colecciones genéricas
- 9. Colecciones Java (estructura LIFO)
- 10. Colecciones similares a Java en Delphi
- 11. ¿Por qué Java varargs no admite colecciones?
- 12. Java Commons Colecciones removeAll
- 13. Colecciones de cadenas rápidas en Java
- 14. Iteraciones sobre colecciones de Java en Scala
- 15. Elevación y tipo de seguridad
- 16. Colecciones de Java con objetos mutables
- 17. ¿Cómo resolver este tipo de advertencia de seguridad de tipo Java?
- 18. solución mejor para las colecciones Backbone.js anidados
- 19. ¿Cuál es la mejor manera de comparar dos colecciones en Java y actuar sobre ellas?
- 20. Java/Scala (profundidad) colecciones interoperabilidad
- 21. ¿Qué biblioteca de Colecciones Java recomienda?
- 22. Conversión de colecciones Java en estructuras de datos Clojure
- 23. La mejor forma de controlar el acceso simultáneo a las colecciones de Java
- 24. Colecciones Java: ¿qué colección usar y cuándo?
- 25. Colecciones de Java con el comodín
- 26. ¿Es posible crear colecciones de Java seguras de tipo cuyos miembros simplemente implementen varias interfaces?
- 27. ¿Cuál es el significado del tipo de advertencia de seguridad en ciertos moldes genéricos de Java?
- 28. Seguridad de subprocesos en la clase Java
- 29. Serialización en java: seguridad automática de hilos?
- 30. ¿El mejor ofuscador de Java?
¿Podría usar una enumeración en lugar de una cadena? Eso puede ser útil cuando tienes claves bien definidas. – Carl