51 votes

Comment transformer List<String> en Map<String,String> avec les collections Google ?

J'ai une liste de chaînes de caractères et j'ai une fonction pour générer une valeur pour chaque clé de la liste.

Je souhaite créer une carte à l'aide de cette fonction. Puis-je le faire avec les collections Google ?

0 votes

Je suppose que vous le savez, mais si la valeur générée par la fonction peut être la même pour deux éléments quelconques de la liste d'origine, vous devrez utiliser la fonction suivante Multimaps.index pour générer un Multimap qui peut stocker plusieurs valeurs pour la même clé.

88voto

dogbane Points 85749

Utilice Maps.uniqueIndex(Iterable, Fonction) :

Retourne une carte immuable pour laquelle la Map.values() sont les éléments donnés dans l'ordre donné, et chaque clé est le produit de l'invocation d'une fonction fournie sur sa valeur correspondante. (extrait de la javadoc)

Ejemplo:

Map<String,String> mappedRoles = Maps.uniqueIndex(yourList, new Function<String,String>() {
  public String apply(String from) {
    // do stuff here
    return result;
  }});

2 votes

Quelles sont les performances de cette solution ? J'aimerais l'utiliser pour plus de 50 000 éléments dans une liste d'objets volumineux. J'utilise actuellement deux cartes distinctes, qui stockent les mêmes objets, mais mappés à des clés différentes. J'aimerais me débarrasser de ces cartes et utiliser une liste (puisque les clés sont déjà des champs de l'objet). Et votre solution me permet de générer les cartes automatiquement à partir de la liste. Mais à quel prix ?

0 votes

@m_pGladiator Je sais que votre question est ancienne, mais la réponse pourrait intéresser d'autres personnes... Je dirais que les méthodes Guava sont fournies plus pour la commodité / lisibilité que pour la performance, en général. Si vous avez un doute, il suffit de s'en tenir aux boucles créées manuellement. Ou utilisez un outil comme Caliper pour mesurer les performances respectives.

0 votes

L'OP dit qu'ils ont "une [fonction] pour générer une valeur pour chaque clé dans la liste". Maps.uniqueIndex génère une clé pour chaque valeur de la liste, ce qui est l'inverse de ce que le PO a demandé. Par conséquent, cette réponse et celle de Sean sont incorrectes et celle de ColinD l'est.

23voto

ColinD Points 48573

À partir du 26/07/2012, Guava master contient deux nouvelles façons de le faire. Elles devraient être dans la version 14.0.

Maps.asMap(Set<K>, Function<? super K, V>) (et deux surcharges pour SortedSet y NavigableSet ) vous permet de visualiser une Set plus un Function en tant que Map où la valeur de chaque clé de l'ensemble est le résultat de l'application de la fonction à cette clé. Le résultat est une vue, il ne copie donc pas l'ensemble d'entrée et la fonction Map Le résultat changera en fonction de l'ensemble et vice versa.

Maps.toMap(Iterable<K>, Function<? super K, V>) prend un Iterable et s'empresse de le convertir en un ImmutableMap où les éléments distincts de l'itérable sont les clés et les valeurs sont les résultats de l'application de la fonction à chaque clé.

15voto

Jon Skeet Points 692016

EDIT : Il est tout à fait possible que Sean ait raison et que j'aie mal compris la question.

Si la liste originale est destinée à être clés alors il semble que vous puissiez utiliser une carte de calcul, par l'intermédiaire de MapMaker.makeComputingMap et ignore la liste d'entrée pour commencer. EDIT : Comme indiqué dans les commentaires, cette fonction est maintenant dépréciée et supprimée dans Guava 15.0. Jetez un coup d'œil à CacheBuilder à la place.

D'un autre côté, cela ne vous donne pas non plus une carte qui retournera null si vous lui demandez une valeur correspondant à une clé qui n'était pas dans la liste au départ. Cela ne vous donne pas non plus En d'autres termes, cela peut très bien no n'est pas approprié, mais cela vaut la peine d'être considéré, en fonction de ce que vous essayez de faire avec :)

Je vais laisser cette réponse ici, à moins que vous ne fassiez un commentaire sur le fait que ni approche ici vous est utile, auquel cas je la supprimerai.


Réponse originale

Utilisation de Goyave vous pouvez le faire assez facilement avec Maps.uniqueIndex :

Map<String, String> map = Maps.uniqueIndex(list, keyProjection);

(J'ai mentionné Guava spécifiquement par opposition aux collections Google, car je n'ai pas vérifié si l'ancien référentiel des collections Google comprenait Maps.uniqueIndex .)

0 votes

makeComputingMap est déprécié, et sa suppression est prévue pour bientôt. code.google.com/p/guava-libraries/wiki/MapMakerMigration

0 votes

@ripper234 : Merci, j'ai ajouté un lien vers CacheBuilder.

0 votes

J'ai pensé à ajouter un lien dans mon commentaire initial, mais est-il facile d'obtenir une carte à partir de CacheBuilder ?

13voto

Sean Patrick Floyd Points 109428

Soit je vous ai mal compris, soit ce sont les autres qui l'ont fait. Je comprends que vous voulez que votre liste soit les clés de la carte, alors que Maps.uniqueIndex() crée des clés pour correspondre à vos valeurs (ce qui est tout le contraire).

Quoi qu'il en soit, il y a un ouvrir le dossier Guava qui demande la fonctionnalité exacte que vous demandez, et j'ai aussi a mis en œuvre une telle solution pour une question précédente.

1 votes

Oui, je pense que tu as peut-être raison. J'ai modifié ma réponse pour mentionner les cartes informatiques, au cas où cela conviendrait au PO, mais je suis tout à fait prêt à supprimer complètement la réponse.

6voto

Carlos Points 139

Utilisation de Guava + Lambda

 Map<String, YourCustomClass> map = Maps.uniqueIndex(YourList, YourCustomClass -> YourCustomClass.getKey());

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X