Wie konvertiere ich eine Map in eine Liste in Java?

671

Was ist der beste Weg, um a Map<key,value>in a umzuwandeln List<value>? Durchlaufen Sie einfach alle Werte und fügen Sie sie in eine Liste ein, oder übersehen Sie etwas?

Javaa
quelle
1
Ich denke, es ist kein gutes Modell, wenn man eine Karte in eine Liste konvertieren muss. Man sollte den Code so schreiben, dass diese Situation nicht eintritt.
Bugs passieren

Antworten:

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

vorausgesetzt:

Map<Key,Value> map;
Cletus
quelle
7
Vielen Dank! Ich ging davon aus Collection, dass die Besetzung von bis Listfunktionieren würde.
Asgs
1
Ich vermute, der Grund, warum es nicht funktioniert, ist, dass die von values ​​() zurückgegebene Sammlung von der zugrunde liegenden Map abhängt. Wenn Sie stattdessen einen Kopierkonstruktoraufruf ausführen, weisen Sie Speicher zu und kopieren die Werte in diesen Speicher, wodurch die Verbindung unterbrochen wird ...
Sheldon R.
4
Wenn wir LinkedHashMap haben - wird die Bestellung gleich bleiben?
1
@ user2022068 Ja, die Reihenfolge sollte mit LinkedHashMap beibehalten werden.
SusanW
1
@SheldonR. Ja - Die von keySet()und zurückgegebenen Sammlungen values()sind Shim-Objekte, die eine Set- oder Collection-Ansicht der zugrunde liegenden Struktur enthalten ( keySet()gibt ein Set zurück, um keine Dupes hervorzuheben). Denn values()das zurückgegebene Objekt kann ein sein List, wird es aber oft nicht sein. Wenn Sie, wie Sie sagen, eine echte Liste erstellen, wird der Link unterbrochen, sodass Sie nicht mehr von der ursprünglichen Karte abhängig sind. Manchmal benötigen Sie jedoch nur eine Liste, da für eine API eine erforderlich ist.
Dies bestätigt
137

Das Problem hierbei ist, dass Mapzwei Werte (ein Schlüssel und ein Wert) vorhanden sind, während a Listnur einen Wert (ein Element) hat.

Daher ist das Beste, was getan werden kann, entweder einen Listder Schlüssel oder die Werte zu erhalten. (Es sei denn, wir erstellen einen Wrapper, um das Schlüssel / Wert-Paar festzuhalten.)

Angenommen, wir haben eine Map:

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

Die Schlüssel als Listkönnen erhalten werden, indem ArrayListaus einem Setvon der Map.keySetMethode zurückgegebenen Schlüssel ein neuer erstellt wird:

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

Während die Werte als erhalten werden Listkönnen, erstellen Sie eine neue ArrayListaus einer Collectionvon der Map.valuesMethode zurückgegebenen:

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

Das Ergebnis des Erhaltens der ListSchlüssel:

Apfel
Ein weiterer
Hallo

Das Ergebnis des Erhaltens der ListWerte:

3.14
Element
Welt
Coobird
quelle
3
Es ist zu beachten, dass die Reihenfolge der von diesen Methoden zurückgegebenen Werte nicht definiert ist und für HashMapund ähnliche nicht sortierte MapImplementierungen effektiv zufällig ist.
Joachim Sauer
1
Ja, Sie müssten wissen, dass es sich um eine LinkedHashMap oder ähnliches handelt. Das Problem mit der ursprünglichen Frage ist, dass die Frage falsch angegeben ist, dh bearbeitet werden muss. Die Frage ist nicht, eine Karte in eine Liste zu konvertieren, sondern wie die Werte der Karte als Liste abgerufen werden. Die Methodenwerte geben Ihnen eine Sammlung, aber keine Liste, und daher ist ein kleiner Trick erforderlich.
Demongolem
Ich denke, Sie könnten Ihrer Antwort hinzufügen, was @ M0les sagt: Dass Sie irgendwie über SortedMap "gehen" müssten. Beginnen Sie entweder mit einer konkreten SortedMap-Implementierung (z. B. TreeMap) oder fügen Sie Ihre Eingabe-Map in eine SortedMap ein, bevor Sie diese um
Ignacio Rubio vom
41

Verwenden der Java 8 Streams-API.

List<Value> values = map.values().stream().collect(Collectors.toList());
Matej Kormuth
quelle
8
Ich bevorzuge die akzeptierte konstruktorbasierte Antwort. Streams sollten zur Vereinfachung des Codes dienen.
Aaron
1
@ Aaron Ja, für die Aufgabe, eine Werteliste von Map zu erhalten, scheint der Konstruktor einfacher zu sein. Wenn Sie Streams jedoch ausgiebig in einer Codebasis verwenden, ist es besser, konsistent zu bleiben.
Matej Kormuth
1
Wenn ich dies verwende, erhalte ich eine Fehlermeldung, wenn ich eine große Datenmenge abrufe. Wenn die Threads eine Endlosschleife bilden, steigt der CPU-Verbrauch an. Looping Threads Stack Trace sind unten angegeben, untersuchen Sie es
Ganesh Giri
24

map.entrySet()bietet Ihnen eine Sammlung von Map.EntryObjekten, die sowohl Schlüssel als auch Wert enthalten. Sie können dies dann in ein beliebiges Sammlungsobjekt umwandeln, z new ArrayList(map.entrySet()).

Java-Typ
quelle
23

eine Liste von was?

Angenommen, es mapist Ihre Instanz vonMap

  • map.values()gibt ein zurück, Collectiondas alle Werte der Karte enthält.
  • map.keySet()gibt ein zurück, Setdas alle Schlüssel der Karte enthält.
Diego Amicabile
quelle
14

Ich denke , Sie wollen die Werte in den enthaltenen umwandeln Mapzu ein list? Am einfachsten ist es, die values()Methode der MapSchnittstelle aufzurufen . Dies gibt die CollectionWertobjekte zurück, die in derMap . .

Beachten Sie, dass dies Collectionvom MapObjekt unterstützt wird und alle Änderungen am MapObjekt hier berücksichtigt werden. Wenn Sie also eine separate Kopie wünschen, die nicht an Ihr MapObjekt gebunden ist , erstellen Sie einfach ein neues ListObjekt, ArrayListindem Sie den folgenden Wert übergeben Collection.

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

Sie können es so machen

List<Value> list = new ArrayList<Value>(map.values());
user3752441
quelle
1
OP fragen, wie in List <Wert> konvertiert werden soll. Wenn Sie Antworten geben, sollten Sie der vorgeschlagenen Lösung eine gute Beschreibung hinzufügen. Diese Frage wurde bereits beantwortet beantwortet.
HaveNoDisplayName
5

Wenn Sie sicherstellen möchten, dass die Werte in der Resultierenden List<Value>in der Schlüsselreihenfolge der Eingabe sind Map<Key, Value>, müssen Sie "über" gehen.SortedMap irgendwie .

Beginnen Sie entweder mit einer konkreten SortedMapImplementierung (z. B. TreeMap) oder fügen Sie Ihre Eingabe Mapin eine ein, SortedMapbevor Sie diese in konvertieren List. z.B:

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

Andernfalls erhalten Sie die native Reihenfolge, die die MapImplementierung bietet. Dies kann häufig etwas anderes sein als die natürliche Schlüsselreihenfolge (Try Hashtableor ConcurrentHashMap, für Abwechslung).

M0les
quelle
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);

Wir können sowohl Schlüssel- als auch Wertepaare in der Liste haben. Sie können auch Schlüssel und Wert mit Map.Entry erhalten, indem Sie über die Liste iterieren.

user11
quelle
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());    
}
saurabhgoyal795
quelle
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());
 } "
Siva Prasad
quelle
1

Hier ist die generische Methode zum Abrufen von Werten aus der Karte.

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;
}
Hiral Pancholi
quelle
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());
}
Hakan Anlamaz
quelle