Comment convertir une carte en liste en Java?

675

Quelle est la meilleure façon de convertir un Map<key,value>en un List<value>? Il suffit d'itérer sur toutes les valeurs et de les insérer dans une liste ou est-ce que j'oublie quelque chose?

Javaa
la source
1
Je pense que ce n'est pas un bon modèle si l'on doit convertir une carte en liste. Il faut écrire le code de telle manière que cette situation ne se reproduise pas.
Bugs Happen

Réponses:

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

en supposant:

Map<Key,Value> map;
cletus
la source
7
Merci! Je supposais que le casting de Collectionà Listfonctionnerait.
asgs
1
Je soupçonne que la raison pour laquelle cela ne fonctionne pas est que la collection retournée par values ​​() dépend de la carte sous-jacente; en effectuant un appel de constructeur de copie à la place, vous allouez du stockage et copiez les valeurs dans ce stockage, rompant ainsi la connexion ...
Sheldon R.
4
Si nous avons LinkedHashMap - la commande restera-t-elle la même?
1
@ user2022068 oui, l'ordre doit être conservé avec LinkedHashMap.
SusanW
1
@SheldonR. yes - les collections retournées par keySet()et values()sont généralement des objets shim qui donnent une vue Set ou Collection de la structure sous-jacente ( keySet()renvoie un Set pour ne mettre en évidence aucune dupe). Car values(), l'objet retourné peut être un List, mais ne le sera souvent pas. La création d'une véritable liste, comme vous le dites, rompt le lien, ce qui signifie que vous ne dépendez plus de la carte d'origine. Parfois cependant, vous n'avez besoin que d'une liste car certaines API en nécessitent une - renforçant la règle selon laquelle une bonne API ne doit nécessiter que les interfaces les plus abstraites avec
lesquelles
137

Le problème ici est qu'il Mapa deux valeurs (une clé et une valeur), tandis Listqu'un a une seule valeur (un élément).

Par conséquent, le mieux qui puisse être fait est d'obtenir une Listdes clés ou des valeurs. (Sauf si nous créons un wrapper pour conserver la paire clé / valeur).

Disons que nous avons Map:

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

Les clés comme un Listpeuvent être obtenues en créant un nouveau à ArrayListpartir d'un Setretourné par la Map.keySetméthode:

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

Alors que les valeurs comme un Listpeuvent être obtenues en créant un nouveau à ArrayListpartir d'un Collectionretourné par la Map.valuesméthode:

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

Le résultat de l'obtention Listdes clés:

Pomme
Un autre
Bonjour

Le résultat de l'obtention Listdes valeurs:

3.14
Élément
Monde
coobird
la source
3
Il convient de noter que l'ordre des valeurs renvoyées par ces méthodes n'est pas défini et pour les implémentations HashMapsimilaires non triées, Mapil sera effectivement aléatoire.
Joachim Sauer
1
Oui, vous devez savoir que c'est un LinkedHashMap ou quelque chose de ce genre. Le problème avec la question d'origine est que la question est inexacte, c'est-à-dire qu'elle a besoin d'être modifiée. La question n'est pas de convertir une carte en liste, mais plutôt de savoir comment obtenir les valeurs de la carte en tant que liste. Les valeurs de la méthode vous donnent une collection, mais pas une liste, et donc la nécessité d'une astuce intéressante.
demongolem
Je pense que vous pourriez ajouter à votre réponse ce que @ M0les dit: Que vous auriez besoin de "passer par" SortedMap d'une manière ou d'une autre. Commencez par une implémentation concrète de SortedMap (telle que TreeMap) ou insérez votre carte d'entrée dans une SortedMap avant de la convertir en List
Ignacio Rubio
41

Utilisation de l'API Java 8 Streams.

List<Value> values = map.values().stream().collect(Collectors.toList());
Matej Kormuth
la source
8
Je préfère la réponse acceptée, basée sur le constructeur. Les flux devraient être destinés à simplifier le code.
Aaron
1
@Aaron Oui, pour la tâche d'obtenir une liste de valeurs de Map, le constructeur semble être plus simple. Cependant, si vous utilisez largement Streams dans une base de code, il est préférable de rester cohérent.
Matej Kormuth
1
lorsque j'utilise cela, obtenez une erreur si je récupère une énorme quantité de données .. le fil est en boucle sur java.util.stream.ReduceOps $ 3.makeSink (source inconnue). Si les threads bouclent à l'infini, la consommation du processeur commencera à augmenter. La trace de la pile des threads en boucle est donnée ci-dessous, examinez-la
Ganesh Giri
24

map.entrySet()vous donne une collection d' Map.Entryobjets contenant à la fois la clé et la valeur. vous pouvez ensuite le transformer en n'importe quel objet de collection que vous aimez, comme new ArrayList(map.entrySet());

mec java
la source
23

une liste de quoi?

En supposant que mapvotre instance deMap

  • map.values()renverra un Collectioncontenant toutes les valeurs de la carte.
  • map.keySet()renverra un Setcontenant toutes les clés de la carte.
Diego Amicabile
la source
14

Je suppose que vous voulez convertir les valeurs contenues dans le Mapun list? Le plus values()simple est d'appeler la méthode de l' Mapinterface. Cela renverra les Collectionobjets de valeur contenus dans le Map.

Notez que cela Collectionest soutenu par l' Mapobjet et toutes les modifications apportées à l' Mapobjet seront reflétées ici. Donc, si vous voulez une copie séparée non liée à votre Mapobjet, créez simplement un nouvel Listobjet comme un ArrayListpassage de la valeur Collectioncomme ci-dessous.

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

Vous pouvez le faire comme ça

List<Value> list = new ArrayList<Value>(map.values());
user3752441
la source
1
OP demande comment convertir en List <value>. Lorsque vous fournissez des réponses, il est préférable d'inclure une bonne description avec la solution proposée. Cette question a déjà reçu une réponse.
HaveNoDisplayName
5

Si vous voulez vous assurer que les valeurs dans la résultante List<Value>sont dans l'ordre des clés de l'entrée Map<Key, Value>, vous devez en SortedMapquelque sorte "passer par" .

Soit commencer avec un béton SortedMapmise en œuvre (telle que TreeMap) ou insérez votre entrée Mapen SortedMapavant de la convertir à List. par exemple:

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

Sinon, vous obtiendrez tout l'ordre natif Mapfourni par l' implémentation, qui peut souvent être autre chose que l'ordre des clés naturelles (Try Hashtableou ConcurrentHashMap, pour varier).

M0les
la source
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);

nous pouvons avoir à la fois la clé et la paire de valeurs dans la liste. Vous pouvez également obtenir la clé et la valeur en utilisant Map.Entry en itérant sur la liste.

user11
la source
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
la source
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
la source
1

Voici la méthode générique pour obtenir des valeurs de la carte.

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
la source
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
la source