Come convertire una mappa in elenco in Java?


675

Qual è il modo migliore per convertire a Map<key,value>in a List<value>? Basta scorrere tutti i valori e inserirli in un elenco o sto trascurando qualcosa?


1
Penso che non sia un buon modello se si deve convertire la mappa in elenco. Si dovrebbe scrivere il codice in modo tale che questa situazione non si risolva.
Bugs Happen

Risposte:


1299
List<Value> list = new ArrayList<Value>(map.values());

assumendo:

Map<Key,Value> map;

7
Grazie! Pensavo che il cast da Collectiona Listavrebbe funzionato.
chiede il

1
Ho il sospetto che il motivo per cui non funziona è perché la raccolta restituita da valori () dipende dalla mappa sottostante; effettuando invece una chiamata del costruttore della copia, allocare memoria e copiare i valori in quella memoria, interrompendo così la connessione ...
Sheldon R.

4
Se abbiamo LinkedHashMap - l'ordine lascerà lo stesso?

1
@ user2022068 sì, l'ordine dovrebbe essere preservato con LinkedHashMap.
SusanW,

1
@SheldonR. sì - le raccolte restituite da keySet()e values()sono generalmente oggetti shim che danno una vista Set o Collection della struttura sottostante ( keySet()restituisce un Set per enfatizzare i non duplicati). Per values(), l'oggetto restituito può essere un List, ma spesso non lo sarà. La creazione di un vero elenco, come dici tu, interrompe il collegamento, il che significa che non sei più dipendente dalla mappa originale. A volte però, hai solo bisogno di un Elenco perché alcune API ne richiedono una - il rafforzamento della regola secondo cui una buona API dovrebbe richiedere solo le interfacce più astratte con cui può cavarsela ...
SusanW

137

Il problema qui è che Mapha due valori (una chiave e un valore), mentre uno Listha un solo valore (un elemento).

Pertanto, il meglio che si può fare è ottenere una Listdelle chiavi o i valori. (A meno che non creiamo un wrapper per aggrapparci alla coppia chiave / valore).

Di 'che abbiamo un Map:

Map<String, String> m = new HashMap<String, String>();
m.put("Hello", "World");
m.put("Apple", "3.14");
m.put("Another", "Element");

Le chiavi come a Listpossono essere ottenute creando una nuova ArrayListda una Setrestituita dal Map.keySetmetodo:

List<String> list = new ArrayList<String>(m.keySet());

Mentre i valori come a Listpossono essere ottenuti creando un nuovo ArrayListda un Collectionrestituito dal Map.valuesmetodo:

List<String> list = new ArrayList<String>(m.values());

Il risultato di ottenere i Listtasti:

Mela
Un altro
Ciao

Il risultato di ottenere i Listvalori:

3.14
Elemento
Mondo

3
Va notato che l'ordine dei valori restituiti da tali metodi non è definito e per implementazioni HashMapsimili non ordinate Mapsarà effettivamente casuale.
Joachim Sauer,

1
Sì, dovresti sapere che è una LinkedHashMap o qualcosa del genere. Il problema con la domanda originale è che la domanda è errata, ovvero ha bisogno di essere modificata. La domanda non è quella di convertire una mappa in un elenco, ma piuttosto come ottenere i valori della mappa come un elenco. I valori del metodo offrono una raccolta, ma non un elenco, e quindi la necessità di un piccolo trucco.
demongolem,

Penso che potresti aggiungere alla tua risposta ciò che dice @ M0les: che dovresti "andare via" in qualche modo SortedMap. O inizia con un'implementazione concreta di SortedMap (come TreeMap) o inserisci la tua mappa di input in una SortedMap prima di convertirla in Elenco
Ignacio Rubio,

41

Utilizzo dell'API Java 8 Streams.

List<Value> values = map.values().stream().collect(Collectors.toList());

8
Preferisco la risposta accettata, basata sul costruttore. Gli stream dovrebbero essere per semplificare il codice.
Aaron,

1
@Aaron Sì, per il compito di ottenere un Elenco di valori da Map il costruttore sembra essere più semplice. Tuttavia, se stai utilizzando gli stream in modo estensivo in una base di codice, è meglio rimanere coerenti.
Matej Kormuth,

1
quando lo uso ottengo un errore se sto recuperando un'enorme quantità di dati. Se i thread si ripetono all'infinito, il consumo della CPU inizierà a salire. Di seguito sono riportate le tracce dello stack di thread in loop, esaminalo
Ganesh Giri il

24

map.entrySet()ti dà una raccolta di Map.Entryoggetti contenente sia la chiave che il valore. puoi quindi trasformarlo in qualsiasi oggetto di raccolta che ti piace, come ad esempio new ArrayList(map.entrySet());


23

un elenco di cosa?

Supponendo che mapsia la tua istanza diMap

  • map.values()restituirà un Collectioncontenente tutti i valori della mappa.
  • map.keySet()restituirà un Setcontenente tutte le chiavi della mappa.

14

Immagino che tu voglia convertire i valori contenuti in Mapa list? Il più semplice è chiamare il values()metodo Mapdell'interfaccia. Questo restituirà il Collectionvalore degli oggetti contenuti in Map.

Si noti che questo Collectionè supportato Mapdall'oggetto e qualsiasi modifica Mapall'oggetto si rifletterà qui. Quindi, se si desidera una copia separata non associata al proprio Mapoggetto, è sufficiente creare un nuovo Listoggetto come ArrayListpassare un valore Collectioncome di seguito.

ArrayList<String> list = new ArrayList<String>(map.values());

6

Puoi farlo in questo modo

List<Value> list = new ArrayList<Value>(map.values());

1
OP chiede come convertire in Elenco <valore>. Quando si forniscono risposte, è meglio includere una buona descrizione con la soluzione proposta. A questa domanda è già stata accettata una risposta.
HaveNoDisplayName

5

Se vuoi assicurarti che i valori nel risultante List<Value>siano nell'ordinamento per chiave dell'input Map<Key, Value>, devi "passare attraverso" in SortedMapqualche modo.

O iniziare con una concreta SortedMapimplementazione (come TreeMap) o inserire il vostro ingresso Mapin una SortedMapprima della conversione che a List. per esempio:

Map<Key,Value> map;
List<Value> list = new ArrayList<Value>( new TreeMap<Key Value>( map ));

Altrimenti otterrai qualsiasi ordinamento nativo Mapfornito dall'implementazione, che spesso può essere qualcosa di diverso dall'ordinamento chiave naturale (Try Hashtableor ConcurrentHashMap, per varietà).


5
    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("java", 20);
    map.put("C++", 45);

    Set <Entry<String, Integer>> set = map.entrySet();

    List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);

possiamo avere sia coppia chiave che valore nell'elenco. Inoltre possiamo ottenere chiave e valore usando Map.Entry ripetendo l'elenco.


4
// you can use this
List<Value> list = new ArrayList<Value>(map.values());

// or you may use 
List<Value> list = new ArrayList<Value>();
for (Map.Entry<String, String> entry : map.entrySet())
{
list.add(entry.getValue());    
}

1
"Map<String , String > map = new HapshMap<String , String>;
 map.add("one","java");
 map.add("two" ,"spring");
 Set<Entry<String,String>> set =  map.entrySet();
 List<Entry<String , String>> list = new ArrayList<Entry<String , String>>    (set);
 for(Entry<String , String> entry : list ) {
   System.out.println(entry.getKey());
   System.out.println(entry.getValue());
 } "

1

Ecco il metodo generico per ottenere valori dalla mappa.

public static <T> List<T> ValueListFromMap(HashMap<String, T> map) {
    List<T> thingList = new ArrayList<>();

    for (Map.Entry<String, T> entry : map.entrySet()) {
        thingList.add(entry.getValue());
    }

    return thingList;
}

1
HashMap<Integer, List<String>> map = new HashMap<>(); 
List<String> list = new ArrayList<String>();
list.add("Java");
list.add("Primefaces");
list.add("JSF");
map.put(1,list);
if(map != null){
    return new ArrayList<String>((Collection<? extends String>) map.values());
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.