i dati raccolti qualcosa comeUn ArrayList creato da keySet() di LinkedHashMap conserva l'ordine di inserimento?
{ "Dipendente 1 della ABC", "ABCX"}, { "Dipendente 2 di ABC", "ABCY"}, { "Dipendente 3 della ABC", "ABCZ "}
dal database tramite un RefCursor
.
Ho un caso in cui ho bisogno di conservare l'ordine in cui i dati vengono letti dal database. Poiché i miei dati sono una specie di "valore-chiave", ho pensato di utilizzare un'implementazione di Map
ordinata. Quindi scelto LinkedHashMap
//defined as a static map inside a common utlity class
public class Common{
public static final LinkedHashMap<String, String> empMap = new LinkedHashMap<String, String>();
}
//rs is the resultset
if (rs != null) {
while (rs.next()) {
key = rs.getString("name_text");
value = rs.getString("id");
Common.empMap.put(key, value);
}
}
devo passare le chiavi al cliente, nello stesso ordine in cui sono stati recuperati dal database (cursore).
List<String> empList = new ArrayList<String>(Common.empMap.keySet());
keySet() -. La documentazione dice "restituisce una visione Set delle chiavi contenute in questa mappa Il set è sostenuta dalla mappa, in modo da modificare la mappa si riflettono nel set, e viceversa"
mi aspetto è che Da ArrayList
è anche un insieme ordinato, devo avere le chiavi nello stesso modo in cui è stato recuperato/inserito nel Map
.
Quando eseguo un programma di prova di esempio, si ottiene come previsto.
public class LinkedMap {
public static void main(String[] args) {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put("Employee 1 of ABC", "ABCX");
map.put("Employee 2 of ABC", "ABCY");
map.put("Employee 3 of ABC", "ABCZ");
ArrayList<String> list = new ArrayList<String>(map.keySet());
System.out.println(list);
}
}
uscita: [Impiegato 1 di ABC, Impiegato 2 di ABC, Impiegato 3 di ABC]
Tuttavia il mio domanda è, se questo è garantito uscita o è che io ricevo solo casualmente, e potrebbe variare,
Update (?): 2015/09/30
Grazie a tutti, ognuno di voi ha contribuito con punti validi.
In sintesi tutte le risposte,
E 'garantito che l'ordine è mantenuto.
Secondo Javadocs,
LinkedHashMap è tabella hash e attuazione lista collegata dell'interfaccia Map , con ordine di iterazione prevedibile. Questa implementazione differisce da HashMap in quanto mantiene una lista doppiamente collegata che esegue attraverso tutte le sue voci.Questa lista collegata definisce l'iterazione ordinamento, che normalmente è l'ordine in cui le chiavi sono state inserite mappa (inserimento-ordine)
cioè: LinkedHashMap
itererà nell'ordine in cui le voci sono state messe in la mappa.
Quindi LinkedHashMap#keySet()
mi darà lo stesso ordine in cui sono state inserite le chiavi sulla mappa, perché lo LinkedHashMap#keySet().iterator()
itera nell'ordine specificato.
Andando in profondità per l'attuazione di iterator()
possiamo vedere che,
LinkedHashMap implementa il metodo newKeyIterator(), che restituisce un'istanza di una classe che eredita LinkedHashIterator, curando l' 'ordinazione'
// These Overrides alter the behavior of superclass view iterator() methods
Iterator<K> newKeyIterator() { return new KeyIterator(); } ...
private class KeyIterator extends LinkedHashIterator<K> {...
private abstract class LinkedHashIterator<T> implements Iterator<T> { ...
per questo: ArrayList<String> list = new ArrayList<String>(map.keySet());
il costruttore ArrayList (Collection) è documented per riempire la lista nell'ordine in cui eleme i nts vengono restituiti dall'iteratore della Collection specificato.
Mi piace come il tipo di variabile sia il più specifico 'LinkedHashMap', invece di una vaga' Mappa' :) – ZhongYu
Penso che avere l'interfaccia o il riferimento di classe concreto non faccia la differenza nel mio caso d'uso. Ma devo ammettere che è stato un errore usare la classe concreta piuttosto che l'interfaccia. O ti senti diverso? – spiderman
no, penso che sia meglio usare il tipo più specifico per le variabili locali/di istanza. – ZhongYu