1067 Stimmen

Java 8 List<V> in Map<K, V> umwandeln

Ich möchte eine Liste von Objekten in eine Map mit Java 8 Streams und Lambdas übersetzen.

So würde ich es in Java 7 und darunter schreiben.

private Map nameMap(List choices) {
        final Map hashMap = new HashMap<>();
        for (final Choice choice : choices) {
            hashMap.put(choice.getName(), choice);
        }
        return hashMap;
}

Das kann ich einfach mit Java 8 und Guava erreichen, aber ich möchte wissen, wie man dies ohne Guava machen kann.

In Guava:

private Map nameMap(List choices) {
    return Maps.uniqueIndex(choices, new Function() {

        @Override
        public String apply(final Choice input) {
            return input.getName();
        }
    });
}

Und Guava mit Java 8 Lambdas.

private Map nameMap(List choices) {
    return Maps.uniqueIndex(choices, Choice::getName);
}

26voto

Renukeswar Punkte 567

Eine weitere Option auf einfache Weise

Map map = new HashMap<>();
choices.forEach(e->map.put(e.getName(),e));

23voto

Piotr Rogowski Punkte 3294

Zum Beispiel, wenn Sie Objektfelder in eine Map konvertieren möchten:

Beispielobjekt:

class Item{
        private String code;
        private String name;

        public Item(String code, String name) {
            this.code = code;
            this.name = name;
        }

        //getter und setter
    }

Und die Operation, um eine Liste in eine Map zu konvertieren:

List list = new ArrayList<>();
list.add(new Item("code1", "name1"));
list.add(new Item("code2", "name2"));

Map map = list.stream()
     .collect(Collectors.toMap(Item::getCode, Item::getName));

13voto

John McClean Punkte 5017

Wenn Sie nichts dagegen haben, 3rd-Party-Bibliotheken zu verwenden, bietet die cyclops-react-Bibliothek von AOL (Offenlegung: Ich bin Mitwirkender) Erweiterungen für alle JDK Collection-Typen, einschließlich List und Map.

ListX choices;
Map map = choices.toMap(c-> c.getName(),c->c);

12voto

Vikas Suryawanshi Punkte 494

Sie können einen Stream der Indizes erstellen, indem Sie einen IntStream verwenden und sie dann in eine Map konvertieren :

Map map = 
IntStream.range(0,items.size())
         .boxed()
         .collect(Collectors.toMap (i -> i, i -> items.get(i)));

12voto

iZian Punkte 323

Ich habe versucht, dies zu tun und festgestellt, dass ich bei Verwendung der obigen Antworten, wenn ich Functions.identity() für den Schlüssel zur Map verwende, Probleme hatte, wenn ich eine lokale Methode wie this::localMethodName verwenden wollte, weil es Probleme mit dem Typ gab.

Functions.identity() tut tatsächlich etwas mit dem Typing in diesem Fall, sodass die Methode nur funktionieren würde, wenn sie Object zurückgibt und ein Parameter des Typs Object akzeptiert.

Um dieses Problem zu lösen, habe ich Functions.identity() aufgegeben und stattdessen s->s verwendet.

Also sieht mein Code, in meinem Fall um alle Verzeichnisse in einem Verzeichnis aufzulisten und für jedes Verzeichnis den Namen des Verzeichnisses als Schlüssel zur Map zu verwenden und dann eine Methode mit dem Verzeichnisnamen aufzurufen und eine Sammlung von Elementen zurückzugeben, so aus:

Map> items = Arrays.stream(itemFilesDir.listFiles(File::isDirectory))
.map(File::getName)
.collect(Collectors.toMap(s->s, this::retrieveBrandItems));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X