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?
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.
Verwenden Sie Guava (frühere Google-Sammlungen) :
%Vor%Oder wenn Sie eine eigene Methode angeben möchten, die% %_der% aus dem Objekt macht:
%Vor%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.)
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.
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: