Esiste un modo per gestire le raccolte annidate in modo più elegante?

8

La mia domanda è piuttosto una domanda di design. Nel mio programma sono arrivato a una struttura dati simile a questa:

private ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>> services  = new ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>>();

C'è un modo per gestire questa struttura dati in modo più elegante? Grazie!

modifica : A, B e C sono classi commerciali. Un'istanza A "può avere" (come associazione) molti Bs e una B "possono avere" molti mapping Integer-C.

    
posta ovdsrn 13.01.2012 - 16:18
fonte

2 risposte

14

Crea una classe Triple con i campi per A , B , Integer , override hashCode() e equals() , e usa Map<Triple,C> invece di Map<A,Map<B,Map<Integer,C>>>

In questo approccio - metti tutti gli elementi in una mappa, con un intervallo di tasti più ampio possibile.

    
risposta data 13.01.2012 - 16:23
fonte
6

[Vengo dallo sfondo C #, ma la risposta dovrebbe essere applicata]

[Non ha molta importanza ma presumo che l'ultimo elemento sia ConcurrentHashMap < C, Integer > ]

Hai una funzione f di tipo A - > (B - > (C - > int)) Se è davvero ciò di cui hai bisogno, non ho una risposta pronta. Ma forse, avendo una funzione f di tipo (A x B x C) - > int sarebbe sufficiente per i tuoi scopi.

La differenza tra due casi è che il primo è più pigro, più funzionale, probabilmente più elegante ed è possibile avere una funzione "parzialmente applicata". Ad esempio, hai un elemento a (di tipo A), applichi a a f e disponi di una funzione g di tipo (B - > (C - > int)) da passare in giro, inviare a metodi, qualunque sia. Tuttavia è un po 'macchinoso e un po' più di codice per inizializzare correttamente la funzione.

Il secondo è più avido e meno elegante, ma potrebbe essere più facile da codificare e capire. Tutto quello che devi fare è avere una classe generica Triple < A, B, C > , sovrascrivere Equals () e GetHashCode () in modo che abbia semantica del valore, (due istanze devono essere considerate uguale se hanno elementi uguali) e dichiarare che ConcurrentHashMap è da Triplo a Intero . Il costo più ovvio da pagare è che devi avere gli elementi A , B , C pronti tutti insieme per creare un'istanza di Triplo ed esegui la ricerca.

Modifica: se l'ultimo elemento è veramente ConcurrentHashMap < C, Integer > , allora la tua classe generica avrà A , B e < strong> Intero e il mapping sarà da Triple < A, B, Integer > a C

    
risposta data 13.01.2012 - 16:45
fonte

Leggi altre domande sui tag