Je veux traduire une liste d'objets en une carte en utilisant les flux et les lambdas de Java 8.
C'est ainsi que je l'écrirais en Java 7 et en dessous.
private Map<String, Choice> nameMap(List<Choice> choices) {
final Map<String, Choice> hashMap = new HashMap<>();
for (final Choice choice : choices) {
hashMap.put(choice.getName(), choice);
}
return hashMap;
}
Je peux accomplir cela facilement en utilisant Java 8 et Guava mais je voudrais savoir comment faire cela sans Guava.
À la goyave:
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, new Function<Choice, String>() {
@Override
public String apply(final Choice input) {
return input.getName();
}
});
}
Et la goyave avec des lambdas Java 8.
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, Choice::getName);
}
java
lambda
java-8
java-stream
Tom Cammann
la source
la source
Maps.uniqueIndex(choices, Choice::getName)
.Seq
de la bibliothèque JOOL (que je recommanderais à tous ceux qui utilisent Java 8), vous pouvez également améliorer la brièveté avec:seq(choices).toMap(Choice::getName)
it -> it
.Function.identity()
est utilisé ici principalement parce qu'il est utilisé dans la documentation référencée et c'est tout ce que je savais sur les lambdas au moment de la rédactionSi votre clé n'est PAS garantie d'être unique pour tous les éléments de la liste, vous devez la convertir en un
Map<String, List<Choice>>
au lieu d'unMap<String, Choice>
la source
Multimaps
méthode de la goyave est-elle une meilleure option? Cela peut être un inconvénient car il ne retourne pas d'Map
objet.Utilisez
getName()
comme clé etChoice
elle - même comme valeur de la carte:la source
Collectors.toMap(Choice::getName,c->c)
(2 caractères plus courts)choices.stream().collect(Collectors.toMap(choice -> choice.getName(),choice -> choice));
fonction première pour la clé, la deuxième fonction de la valeurc -> c
maisFunction.identity()
porte plus d'informations sémantiques. J'utilise généralement une importation statique pour que je puisse simplement l'utiliseridentity()
En voici une autre au cas où vous ne voudriez pas utiliser Collectors.toMap ()
la source
Collectors.toMap()
ou notre propre HashMap comme vous l'avez montré dans l'exemple ci-dessus?La plupart des réponses répertoriées manquent un cas lorsque la liste contient des éléments en double . Dans ce cas, la réponse sera lancée
IllegalStateException
. Reportez-vous au code ci-dessous pour gérer également les doublons de liste :la source
la source
Par exemple, si vous souhaitez convertir des champs d'objet en carte:
Exemple d'objet:
Et l'opération convertit la liste en carte:
la source
Si cela ne vous dérange pas d'utiliser des bibliothèques tierces, la bibliothèque cyclops-react d'AOL (divulgation, je suis un contributeur) a des extensions pour tous les types de collections JDK , y compris List et Map .
la source
J'essayais de le faire et j'ai constaté que, en utilisant les réponses ci-dessus, lors de l'utilisation
Functions.identity()
de la clé de la carte, j'avais des problèmes avec l'utilisation d'une méthode locale commethis::localMethodName
travailler réellement en raison de problèmes de frappe.Functions.identity()
fait en fait quelque chose à la frappe dans ce cas, de sorte que la méthode ne fonctionnerait qu'en retournantObject
et en acceptant un paramètre deObject
Pour résoudre ce problème, j'ai fini par abandonner
Functions.identity()
et utiliser à las->s
place.Donc, mon code, dans mon cas, pour répertorier tous les répertoires à l'intérieur d'un répertoire, et pour chacun utilise le nom du répertoire comme clé de la carte, puis appelle une méthode avec le nom du répertoire et renvoie une collection d'éléments, ressemble à:
la source
Vous pouvez créer un flux d'index à l'aide d'un IntStream puis les convertir en carte:
la source
J'écrirai comment convertir une liste en carte en utilisant des génériques et une inversion de contrôle . Méthode juste universelle!
Peut-être avons - nous une liste d'entiers ou une liste d' objets. La question est donc la suivante: quelle devrait être la clé de la carte?
créer une interface
utilisant maintenant l'inversion de contrôle:
Par exemple, si nous avons des objets de livre, cette classe consiste à choisir la clé de la carte
la source
J'utilise cette syntaxe
la source
groupingBy
crée unMap<K,List<V>>
, pas unMap<K,V>
.String getName();
(pas Integer)la source
Cela peut se faire de 2 manières. Que personne soit la classe que nous allons utiliser pour le démontrer.
Soit les personnes la liste des personnes à convertir sur la carte
1.Utilisation de foreach simple et d'une expression lambda sur la liste
2.Utilisez les collecteurs sur le flux défini dans la liste donnée.
la source
Il est possible d'utiliser des flux pour ce faire. Pour supprimer le besoin d'utiliser explicitement
Collectors
, il est possible d'importer detoMap
manière statique (comme recommandé par Effective Java, troisième édition).la source
Voici la solution de StreamEx
la source
Sert même ce but pour moi,
la source
Si chaque nouvelle valeur pour le même nom de clé doit être remplacée:
Si tous les choix doivent être regroupés dans une liste pour un nom:
la source
la source
Comme alternative à
guava
on peut utiliser kotlin-stdlibla source
Clé de publication AA {12 = ASDFASDFASDF, 7 = EEDDDAD, 4 = CCCC, 3 = BBB, 2 = AA}
la source