JavaRush /Java Blog /Random-IT /Le 9 domande principali sulla mappa in Java
Treefeed
Livello 21

Le 9 domande principali sulla mappa in Java

Pubblicato nel gruppo Random-IT
Ricordiamo che una mappa è un dato strutturato costituito da un insieme di coppie chiave-valore e ciascuna chiave può essere utilizzata solo una volta in una singola mappa. Questo argomento copre 9 domande di base sull'utilizzo di Map in Java e sulle classi implementate. Per semplicità, userò le generalizzazioni negli esempi . Pertanto scriverò semplicemente Map, senza specificare lo specificatore Map. Ma puoi supporre che entrambi i valori di K e V siano comparabili, il che significa che K estende Comparable e V estende anche Comparable .Le 9 domande principali sulla mappa in Java - 1

0. Conversione di una mappa in un elenco

In Java, l' interfaccia Mappa offre tre tipi di raccolte: un set di chiavi, un set di valori e un set di valori-chiave. Tutti possono essere trasformati in un List utilizzando il costruttore o il metodo addAll(). Il frammento di codice seguente illustra come creare un ArrayList da una mappa.
// list of keys
List keyList = new ArrayList(Map.keySet());
//list of values
List valueList = new ArrayList(Map.valueSet());
//list key-value
List entryList = new ArrayList(Map.entrySet());

1. Passa in rassegna tutti i valori nella mappa

Percorrere ciascuna coppia chiave-valore è la procedura più elementare per percorrere una mappa. In Java, ogni coppia viene memorizzata in un campo Map chiamato Map.Entry . Map.entrySet()restituisce un insieme di valori-chiave, quindi il modo più efficiente per scorrere tutti i valori di una mappa sarebbe:
for(Entry entry: Map.entrySet()) {
  //get the key
  K key = entry.getKey();
  //get value
  V value = entry.getValue();
}
Possiamo anche usare Iterator, soprattutto nelle versioni precedenti a JDK 1.5
Iterator itr = Map.entrySet().iterator();
while(itr.hasNext()) {
  Entry entry = itr.next();
  //get the key
  K key = entry.getKey();
  //get value
  V value = entry.getValue();
}

2. Ordinazione della mappa tramite chiavi

Organizzare le mappe per tasti è un'altra procedura comunemente utilizzata. Il primo modo è aggiungere Map.Entry all'elenco e ordinare utilizzando un comparatore che ordina in base ai valori.
List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {

  @Override
  public int compare(Entry e1, Entry e2) {
    return e1.getKey().compareTo(e2.getKey());
  }
});
Un altro modo: utilizzare SortedMap , che, inoltre, dispone anche le sue chiavi in ​​ordine. Tuttavia, tutte le chiavi devono incorporare Comparable o essere accettate dal comparatore. Una delle classi implementate SortedMapè TreeMap . Il suo costruttore accetta un comparatore. Il codice seguente mostra come trasformarne uno normale Mapin uno ordinato.
SortedMap sortedMap = new TreeMap(new Comparator() {

  @Override
  public int compare(K k1, K k2) {
    return k1.compareTo(k2);
  }

});
sortedMap.putAll(Map);

3. Mappa dell'ordine in base ai valori

In questo caso l'aggiunta di una mappa all'elenco e il relativo ordinamento funzionano, ma questa volta è necessario utilizzare Entry.getValue(). Il codice seguente è quasi lo stesso di prima.
List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {

  @Override
  public int compare(Entry e1, Entry e2) {
    return e1.getValue().compareTo(e2.getValue());
  }

});
Possiamo ancora usarlo SortedMapin questo caso, ma solo se i valori sono univoci. In questo caso, puoi trasformare la coppia chiave-valore in una chiave-valore. Questa soluzione presenta gravi limitazioni e non è consigliata da me.

4. Inizializzazione di una mappa statica/immutabile

Quando vuoi che una mappa rimanga immutabile, un buon modo è copiarla su una mappa immutabile. Questa tecnica di programmazione difensiva ti aiuterà a creare una mappa che non solo sia sicura da usare, ma anche thread-safe. Per inizializzare una mappa statica/immutabile, possiamo utilizzare un inizializzatore static(vedi sotto). Il problema con questo codice è che nonostante dichiariamo una Map come static final, possiamo ancora lavorarci dopo l'inizializzazione, ad esempio Test.Map.put(3,"three");. Quindi non è vera immutabilità. Per creare una mappa immutabile utilizzando un inizializzatore statico, abbiamo bisogno di una classe super anonima, che aggiungeremo alla mappa immutabile nell'ultimo passaggio di inizializzazione. Si prega di guardare la seconda parte del codice. Quando verrà generata un'eccezione UnsupportedOperationException se si esegue Test.Map.put(3,"three");.
public class Test {

  private static final Map Map;
  static {
    Map = new HashMap();
    Map.put(1, "one");
    Map.put(2, "two");
  }
}
public class Test {

  private static final Map Map;
  static {
    Map aMap = new HashMap();
    aMap.put(1, "one");
    aMap.put(2, "two");
    Map = Collections.unmodifiableMap(aMap);
  }
}
La libreria Guava supporta anche vari modi per inizializzare raccolte statiche e immutabili. Per ulteriori informazioni sui vantaggi dell'utilità delle raccolte immutabili di Guava, vedere la sezione Raccolte immutabili nel Guava How-to .

5. Differenza tra HashMap, TreeMap e Hashtable

Esistono tre implementazioni principali dell'interfaccia Map in Java: HashMap , TreeMap e Hashtable . Le differenze principali sono le seguenti:
  • Ordine di passaggio . HashMap e HashTable non garantiscono l'ordinamento della Mappa; in particolare non garantiscono che l'ordine rimanga identico nel tempo. Ma TreeMapordinerà tutti i valori nell'ordine naturale delle chiavi o tramite un comparatore.
  • Coppie chiave-valore valide. HashMapti consente di avere una chiave nulla e un valore nullo. HashTablenon consente una chiave nulla o un valore nullo. Se TreeMapviene utilizzato l'ordine naturale o il comparatore non consente una chiave nulla, verrà generata un'eccezione.
  • Sincronizzazione . Solo HashTablesincronizzato, il resto no. Tuttavia, "se non è necessaria un'implementazione thread-safe, si consiglia di utilizzare " HashMapinvece HashTable.
Confronto più dettagliato
.                       | HashMap | HashTable | TreeMap
-------------------------------------------------------

Упорядочивание          |нет      |нет        | да
null в ключ-meaning    | да-да   | нет-нет   | нет-да
синхронизировано        | нет     | да        | нет
производительность      | O(1)    | O(1)      | O(log n)
воплощение              | корзины | корзины   | красно-чёрное дерево
Maggiori informazioni sulla relazione HashMap vs. Mappa ad albero vs. Tabella hash vs. LinkedHashMap .

6. Mappa con ricerca/visualizzazione inversa

A volte abbiamo bisogno di una serie di coppie chiave-chiave, il che significa che i valori sono unici quanto le chiavi (uno schema uno a uno). Questa coerenza consente di creare una "vista/ricerca invertita" sulla Mappa. Cioè, possiamo trovare una chiave in base al suo valore. Questa struttura dati è chiamata mappa bidirezionale , che sfortunatamente non è supportata dal JDK. Sia Apache Common Collections che Guava offrono implementazioni di mappe bidirezionali chiamate rispettivamente BidiMap e BiMap. Entrambi introducono un vincolo che impone una mappatura 1:1 tra chiavi e valori.

7. Copia superficiale della mappa

Quasi tutte, se non tutte, le mappe in Java contengono un costruttore di copia per un'altra mappa. Ma la procedura di copia non è sincronizzata. Ciò significa che quando un thread copia una mappa, un altro thread può modificarne la struttura. Per evitare un'improvvisa desincronizzazione della copia, in questo caso è necessario utilizzarne uno Collections.synchronizedMap().
Map copiedMap = Collections.synchronizedMap(Map);
Un altro modo interessante per copiare superficialmente è utilizzare l'estensione clone(). Ma NON è consigliato nemmeno dal creatore del framework delle raccolte Java, Joshua Bloch. Nel dibattito " Copy Constructor vs. Cloning ", prende posizione: Citazione: "Spesso fornisco un metodo di clonazione pubblica in classi concrete perché le persone si aspettano che siano lì. ... è un peccato che la clonazione non funzioni, ma è successo... La clonazione è un punto debole e penso che le persone dovrebbero essere avvertite dei suoi limiti." Per questo motivo non ti mostro nemmeno come utilizzare il metodo clone()per copiare Map

8. Crea una mappa vuota

Se Mapimmutabile, utilizzare:
Map = Collections.emptyMap();
Oppure utilizzare qualsiasi altra forma di realizzazione. Per esempio:
Map = new HashMap();
FINE
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION