Java: Wie konvertiert man eine Liste? zu einem MapString? [Duplikat]

7

Ich möchte einen Weg finden, die objektspezifische Routine unten zu verwenden und sie zu einer Methode zu abstrahieren, die eine Klasse, eine Liste und einen Feldnamen übergeben kann, um eine Map zurück zu bekommen. Wenn ich einen allgemeinen Zeiger auf das verwendete Muster bekommen könnte oder etc, könnte das mich in die richtige Richtung bringen.

%Vor%

dazu? (Pseudocode)

%Vor%

ist es möglich?

    
ebt 07.07.2010, 23:28
quelle

6 Antworten

1

Folgendes würde ich tun. Ich bin mir nicht ganz sicher, ob ich mit Generika richtig handle, aber na ja:

%Vor%

Übergeben Sie einfach eine Collection, und implementieren Sie die Klassen toString (), um den Namen zurückzugeben. Polymorphismus wird dafür sorgen.

    
quantumSoup 07.07.2010, 23:51
quelle
33

Verwenden Sie Guava (frühere Google-Sammlungen) :

%Vor%

Oder wenn Sie eine eigene Methode angeben möchten, die% %_der% aus dem Objekt macht:

%Vor%     
Jorn 08.07.2010 00:28
quelle
3

Vermeide Reflexionen wie die Pest.

Leider ist die Syntax von Java dafür ausführlich. (Ein kürzlich veröffentlichter JDK7-Vorschlag würde es viel mehr berücksichtigen.)

%Vor%

Zur Zeit anrufen als:

%Vor%

In JDK7 könnte es etwa so aussehen:

%Vor%

(Möglicherweise muss ein yield drin sein.)

    
Tom Hawtin - tackline 08.07.2010 00:22
quelle
3

Java 8 Streams und Methodenreferenzen machen dies so einfach, dass Sie dafür keine Hilfsmethode benötigen.

%Vor%

Wenn doppelte Schlüssel vorhanden sind, können Sie die Werte mit dem toMap Überladung, die eine Wert merge-Funktion nimmt , oder Sie können groupingBy zum Sammeln in eine Liste :

%Vor%

Wie oben gezeigt, ist nichts davon spezifisch für String - Sie können einen Index für jeden Typ erstellen.

Wenn Sie viele zu verarbeitende Objekte haben und / oder Ihre Indexierungsfunktion teuer ist, können Sie mit Collection.parallelStream() oder stream().parallel() parallel arbeiten ( sie tun das gleiche ). In diesem Fall könnten Sie toConcurrentMap oder groupingByConcurrent , da sie es der Stream-Implementierung erlauben, Elemente einfach in eine ConcurrentMap zu laden, anstatt für jeden Thread separate Maps zu erstellen und diese anschließend zusammenzuführen.

Wenn Sie nicht an der Aufruf-Site an Foo::getName (oder eine bestimmte Methode) übergeben möchten, können Sie eine Funktion verwenden, die von einem Aufrufer übergeben wurde, in einem Feld gespeichert ist usw. Wer auch immer die Funktion erstellt kann immer noch Methodenreferenz oder Lambda-Syntax nutzen.

    
Jeffrey Bosboom 19.09.2014 14:46
quelle
1

Verwenden von Reflektion und Generika:

%Vor%

Stellen Sie in Ihrer Dokumentation sicher, dass Sie erwähnen, dass der Rückgabetyp der Methode ein String sein muss. Andernfalls wird eine ClassCastException ausgelöst, wenn versucht wird, den Rückgabewert zu konvertieren.

    
Michael 07.07.2010 23:47
quelle
1

Wenn Sie sicher sind, dass jedes Objekt in List einen eindeutigen Index hat, verwenden Sie Guava mit Jorns Vorschlag von Maps.uniqueIndex .

Wenn andererseits mehr als ein Objekt den gleichen Wert für das Indexfeld hat (was, obwohl es für Ihr spezifisches Beispiel vielleicht nicht wahr ist, in vielen Anwendungsfällen für diese Art von Sache gilt), desto mehr Diese Indizierung wird im Allgemeinen mit Multimaps.index (Iterable & lt; V & gt; -Werte, Function & lt; Super V, K & gt; keyFunction) , um ein ImmutableListMultimap<K,V> zu erzeugen, das jeden Schlüssel zuordnet ein oder mehrere übereinstimmende Werte.

Hier ist ein Beispiel, das eine benutzerdefinierte Function verwendet, die einen Index für eine bestimmte Eigenschaft eines Objekts erstellt:

%Vor%     
ColinD 08.07.2010 01:18
quelle

Tags und Links