2012-11-23 14 views
5

Ho una classe con diversi elenchi di valori-chiave. Ogni chiave (all'interno di una lista) dovrebbe essere unica, quindi uso HashMap. Quando da qualche parte nel codice aggiungo un nuovo elemento a un elenco, sto usando lo put(K, V) di HashMap. Mi piacerebbe che il mio codice generasse un'eccezione se si tenta di aggiungere un elemento con una chiave già esistente. E, poiché tale aggiunta viene eseguita in molti punti del programma, vorrei evitare di aggiungere il controllo in ognuno di essi. Quindi dovrebbe essere la classe list stessa che non consentirebbe di sostituire la coppia chiave-valore esistente.HashMap con controllo di univocità

Ho pensato di estendere la classe HashMap con la mia, che eseguiva tale controllo e generava un'eccezione. Tuttavia, lo put di HashMap non genera eccezioni, quindi non posso farlo neanche io.

Quale sarebbe un buon approccio per ottenere tale comportamento? Sono pronto a sostituire HashMap con qualcosa di meglio, ma ho bisogno che sia veloce sia nell'aggiunta che nel recupero degli oggetti.

Aggiornamento: Grazie a tutti per molti suggerimenti. Dato che sono un novizio completo in Java, ora ho bisogno di imparare molto per essere in grado di scegliere il migliore :) Comunque, sono grato per aver ottenuto così tante opzioni in una pausa pranzo!

+0

Le raccolte Commons non hanno l'esposizione che merita ... – Isaac

risposta

0

È possibile generare un'eccezione che estende RuntimeException.

+2

Ehi tu downvoter, la mia risposta è valida. Spiega il motivo del downvote – AlexWien

+1

Non ero il downvoter, ma credo che la ragione del downvoting sia stata la proposta di una soluzione che richiederebbe all'OP di codificare esplicitamente il controllo della duplicità, mentre l'OP afferma chiaramente che stanno cercando per un meccanismo che lo farà automaticamente. – Isaac

+1

@AlexWien Non ho fatto downvote ma violerebbe il Principio di sostituzione di Liskov. – Mik378

2

Diverse idee:
A. Genera un'eccezione che estende RuntimeException nella classe che estende HashMap.
B. Fornire una sorta di MapWrapper che riceverà una mappa come parametro, avrà get, put, e alcuni altri metodi, con firme che si adattano di più.

+0

'B' esiste già. Vedi la mia risposta qui sotto. – Isaac

+0

violazione di @zaske Liskov anche qui. – Mik378

+0

@ Mik378, 'A' qui viola LSP; 'B' no. Ma 'B' è già disponibile nelle Collezioni Commons (vedi la mia risposta), non c'è bisogno di reinventare la ruota. – Isaac

7

È possibile utilizzare Commons Collections per questo, qualcosa di simile a:

Map map = MapUtils.predicatedMap(new HashMap(), PredicateUtils.uniquePredicate(), 
      null); 

Questo creerà un'istanza Map che un'eccezione ogni volta che si tenta di inserire una coppia valore-chiave quando la stessa chiave esiste già.

Naturalmente, è possibile personalizzare questo comportamento costruendo la propria istanza Predicate e utilizzandola invece di PredicateUtils.uniquePredicate(). Il tuo Predicate può fare tutto ciò che ti serve, per esempio, potrebbe lanciare un tipo diverso di eccezione rispetto a quello lanciato dal default uniquePredicate().

6

non vorrei estendere HashMap di classe, dal momento che in questo caso, sarebbe portare ad una violazione della Liskov principio di sostituzione perché si altera il comportamento di un metodo della classe base.

Invece vorrei usare la composizione:

Creare la classe CustomHashMap attuazione Map interfaccia e con un campo di HashMap. E redeclare tutti i metodi presenti nella classe HashMap, aggiungendo una delega all'originale HashMap per ciascuno eccetto il metodo put() => genera un'eccezione se entry esiste già.

+0

+1 per aver menzionato LSP, e grazie per la soluzione. – texnic

0

È possibile estendere HashMap e generare un'eccezione che è sottoclasse di RuntimeException o una delle eccezioni già generate dal metodo put.

1

Il javadoc for Map#put states:

tiri IllegalArgumentException se alcune proprietà della chiave o il valore specificato impedisce di essere memorizzati in questa mappa

Penso che il tuo caso d'uso rientra in quella categoria e Vorrei quindi usare questa possibilità. Poiché si tratta di un'eccezione non controllata, è possibile utilizzare la composizione, racchiudere un numero HashMap e creare un valore IllegalArgumentException su duplicati nel metodo put.