Mi pregunta es más bien una pregunta de diseño. En mi programa llegué a una estructura de datos que se parece a esto:
private ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>> services = new ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>>();
¿Hay alguna manera de manejar esa estructura de datos de manera más elegante? ¡Gracias!
editar : A, B y C son clases de negocios. Una instancia A "puede tener" (como asociación) muchos Bs y una B "puede tener" muchas asignaciones Integer-C.
java
design
data-structures
ovdsrn
fuente
fuente

A,ByC? Sería más fácil responder si pudiera entender el significado de la anidación de tres niveles de sus mapas de has allí.ConcurrentHashMaps en cada nivel de anidamiento?Respuestas:
Crear una clase
Triplecon los campos paraA,B,Integer, anulaciónhashCode()yequals(), y el usoMap<Triple,C>en lugar deMap<A,Map<B,Map<Integer,C>>>En este enfoque, coloca todos los elementos en un mapa, con un mayor rango posible de claves.
fuente
(A,B,Integer)->C, y por lo tanto, elMapuso anidado . La edición también es compatible con mi precepción.equals, esto solo funcionará si las claves forman una relación de equivalencia. Recientemente me encontré con una situación como esta en la que no lo hicieron: el tercer componente de la clave podría ser un valor predeterminado que aceptaría cualquier instancia, o algún valor concreto, con todos los valores concretos diferentes entre sí. Por lo tanto, cualquier valor concreto tendría que considerarse igual al valor predeterminado, y por transitividad, todos tendrían que ser iguales entre sí, lo que no eran.[Vengo de C # de fondo, pero la respuesta debería aplicarse]
[No importa mucho, pero supongo que el último elemento es ConcurrentHashMap <C, Integer> ]
Tiene una función f de tipo A -> (B -> (C -> int)) Si realmente es lo que necesita, no tengo una respuesta lista. Pero tal vez, tener una función f de tipo (A x B x C) -> int sería suficiente para sus propósitos.
La diferencia entre dos casos es que el primero es más vago, más funcional, posiblemente más elegante y es posible tener una función "parcialmente aplicada". Por ejemplo, tiene un elemento a (de tipo A), aplica a a f y tiene una función g de tipo (B -> (C -> int)) para pasar, enviar a métodos, lo que sea. Sin embargo, es un poco engorroso y un poco más de código para inicializar correctamente la función.
El segundo es más entusiasta y menos elegante, pero puede ser más fácil de codificar y comprender. Todo lo que necesita hacer es tener una clase genérica Triple <A, B, C> , anular Equals () y GetHashCode () para que tenga semántica de valor (dos instancias deben considerarse iguales si tienen elementos iguales) y declarar que el ConcurrentHashMap es de Triple a Entero . El costo de pago más obvio es que necesita tener los elementos A , B , C listos de una vez para crear una instancia de Triple y realizar la búsqueda.
Editar: Si el último elemento es realmente ConcurrentHashMap <C, Integer> , su clase genérica tendrá campos A , B e Integer , y la asignación será de Triple <A, B, Integer> a C
fuente
Triplelugar deMyClassaclarar; También hay implementaciones de n-tuplas en la web, si eres realmente vago.