2009-03-25 21 views
341

Sto cercando una classe in java che abbia un'associazione valore-chiave, ma senza utilizzare gli hash. Ecco cosa sto facendo attualmente:Classe Java che implementa la mappa e mantiene l'ordine di inserimento?

  1. Aggiungere valori a Hashtable.
  2. Ottenere un iteratore per Hashtable.entrySet().
  3. Scorrere tutti i valori e:
    1. Prendi un Map.Entry per l'iteratore.
    2. Creare un oggetto di tipo Module (una classe personalizzata) in base al valore.
    3. Aggiungi la classe a un JPanel.
  4. Mostra il pannello.

Il problema con questo è che non ho il controllo sull'ordine di ritorno dei valori, quindi non posso visualizzare i valori nell'ordine specificato (senza codificare l'ordine).

si usa un ArrayList o Vector per questo, ma più avanti nel codice ho bisogno di afferrare l'oggetto Module per una data chiave, che non posso fare con un ArrayList o Vector.

Qualcuno sa di una classe Java gratuita/open source che eseguirà questa operazione o un modo per ottenere valori da un Hashtable in base a quando sono stati aggiunti?

Grazie!

+1

Non è necessario utilizzare entryset/map.entry. è possibile eseguire iterazioni su chiavi e valori utilizzando hashtable.keys come enumerazione o utilizzando hashtable.keyset.iterator. –

+4

Mi sono preso la libertà di cambiare il titolo, dal momento che non usare gli hash non è in realtà il problema, ma mantenere l'ordine di inserimento. –

risposta

552

Suggerisco uno LinkedHashMap o uno TreeMap. A LinkedHashMap mantiene le chiavi nell'ordine in cui sono state inserite, mentre un TreeMap viene ordinato in ordine tramite Comparator o l'ordinamento naturale degli elementi Comparable.

Poiché non è necessario mantenere ordinati gli elementi, LinkedHashMap dovrebbe essere più veloce per la maggior parte dei casi; TreeMap ha prestazioni O(log n) per containsKey, get, put e remove, secondo Javadocs, mentre LinkedHashMap è O(1) per ciascuna.

Se l'API che prevede solo un ordinamento prevedibile, a differenza di un ordine specifico, considera l'utilizzo delle interfacce implementate da queste due classi, NavigableMap o SortedMap. Ciò ti consentirà di non divulgare implementazioni specifiche nella tua API e di passare a una di queste classi specifiche oa un'implementazione completamente diversa a volontà in seguito.

+2

Questo non funzionerà per me perché, come per javadocs, questo fornisce solo valori ordinati (tramite la chiamata values ​​()). C'è un modo per ottenere istanze Map.Entry ordinate? –

+1

@CoryKendall: TreeMap non funziona? Dovrebbe essere ordinato per chiavi, non per valori. –

+1

Errore mio, pensavo che i set non fossero stati ordinati. –

1

Non so se è opensource, ma dopo un po 'su Google ho trovato this implementation of Map using ArrayList. Sembra essere pre-1.5 Java, quindi potresti volerlo generalizzare, il che dovrebbe essere facile. Nota che questa implementazione ha accesso O (N), ma questo non dovrebbe essere un problema se non aggiungi centinaia di widget al tuo JPanel, cosa che non dovresti comunque.

5

È possibile mantenere uno Map (per ricerca rapida) e List (per ordine) ma uno LinkedHashMap può essere il più semplice. Puoi anche provare un SortedMap ad es. TreeMap, che ha qualsiasi ordine specificato.

13

Se una mappa immutabile si adatta alle vostre esigenze poi c'è una biblioteca da parte di Google chiamato guava (vedi anche guava questions)

Guava fornisce un ImmutableMap con ordine di iterazione specificato dall'utente affidabile. Questo ImmutableMap ha prestazioni O (1) per containsKey, get. Ovviamente mettere e rimuovere non sono supportati.

ImmutableMap scopi vengono realizzati utilizzando uno dei metodi di convenienza eleganti statici of() e copyOf() o un oggetto Builder.

2

LinkedHashMap restituirà gli elementi nell'ordine in cui sono stati inseriti nella mappa quando si esegue l'iterazione su keySet(), entrySet() o values ​​() della mappa.

Map<String, String> map = new LinkedHashMap<String, String>(); 

map.put("id", "1"); 
map.put("name", "rohan"); 
map.put("age", "26"); 

for (Map.Entry<String, String> entry : map.entrySet()) { 
    System.out.println(entry.getKey() + " = " + entry.getValue()); 
} 

Questo stamperà gli elementi nell'ordine in cui sono stati messi in mappa:

id = 1 
name = rohan 
age = 26 
0

Ogni volta che ho bisogno di mantenere l'ordine naturale delle cose che sono noti prima del tempo, io uso un EnumMap

le chiavi saranno enumerate e tu puoi inserire in qualsiasi ordine tu voglia ma quando iterate itererà nell'ordine enum (l'ordine naturale).

Anche quando si utilizza EnumMap non ci dovrebbero essere collisioni che possono essere più efficienti.

Ho davvero trovato che l'utilizzo di enumMap rende il codice leggibile pulito. Ecco uno example

Problemi correlati