ich brauche ein Karte Funktion. Gibt es sowas schon in Java?
(Für diejenigen, die sich fragen: Ich weiß natürlich, wie man diese triviale Funktion selbst implementiert …)
Albert
ich brauche ein Karte Funktion. Gibt es sowas schon in Java?
(Für diejenigen, die sich fragen: Ich weiß natürlich, wie man diese triviale Funktion selbst implementiert …)
leventov
Seit Java 8 gibt es dafür einige Standardoptionen im JDK:
Collection<E> in = ...
Object[] mapped = in.stream().map(e -> doMap(e)).toArray();
// or
List<E> mapped = in.stream().map(e -> doMap(e)).collect(Collectors.toList());
Sehen java.util.Collection.stream()
und java.util.stream.Collectors.toList()
.
Das ist so wortreich, dass es mich innerlich verletzt.
– Natix
29. Januar 2014 um 13:48 Uhr
@ Natix stimme zu toList()
. Austausch gegen einen anderen Typ: (List<R>)((List) list).replaceAll(o -> doMap((E) o));
– leventow
29. Januar 2014 um 18:35 Uhr
dürfen e -> doMap(e)
durch einfach ersetzt werden doMap
?
– Jamesfischer
26. August 2014 um 15:02 Uhr
@jameshfisher, ja, so etwas wie foo::doMap
oder Foo::doMap
.
– leventow
27. August 2014 um 6:26 Uhr
Ich denke, das ist der Grund, warum Scala existiert. Warten Sie, bis Java 12 etwas Lesbares hat.
– JulienD
2. Juli 2017 um 10:44 Uhr
Sean Patrick Floyd
Ab Java 6 gibt es im JDK keine Funktion mehr.
Guave hat ein Funktion Schnittstelle aber und die
Collections2.transform(Collection<E>, Function<E,E2>)
-Methode bietet die von Ihnen benötigte Funktionalität.
Beispiel:
// example, converts a collection of integers to their
// hexadecimal string representations
final Collection<Integer> input = Arrays.asList(10, 20, 30, 40, 50);
final Collection<String> output =
Collections2.transform(input, new Function<Integer, String>(){
@Override
public String apply(final Integer input){
return Integer.toHexString(input.intValue());
}
});
System.out.println(output);
Ausgabe:
[a, 14, 1e, 28, 32]
Heutzutage gibt es mit Java 8 tatsächlich eine Kartenfunktion, also würde ich den Code wahrscheinlich prägnanter schreiben:
Collection<String> hex = input.stream()
.map(Integer::toHexString)
.collect(Collectors::toList);
Es ist erwähnenswert, dass Sie mit Guava zusammen sind kann Wenn Sie dies tun, möchten Sie vielleicht nicht: code.google.com/p/guava-libraries/wiki/FunctionalExplained (Lesen Sie den Abschnitt „Warnhinweise“).
– Adam Parkin
7. März 2013 um 22:32 Uhr
@AdamParkin stimmt, aber ich bin mir ziemlich sicher, dass sich das auf fortgeschrittenere Funktionskonzepte bezieht, sonst hätten sie das nicht entwickelt verwandeln() Methoden an erster Stelle
– Sean Patrick Floyd
8. März 2013 um 10:35 Uhr
Eigentlich nein, es gibt oft einen deutlichen Leistungseinbruch bei funktionalen Idiomen, weshalb sie betonen, dass Sie die Einrichtungen nur verwenden sollten, wenn Sie sicher sind, dass sie die beiden skizzierten Kriterien erfüllen: Nettoeinsparungen von LOC für die Codebasis als Ganzes und bewährt Leistungsgewinne aufgrund fauler Bewertung (oder zumindest keine Leistungstreffer). Sie argumentieren nicht gegen deren Verwendung, sondern weisen nur darauf hin, dass Sie die Warnungen der Implementierer beachten sollten, wenn Sie dies tun.
– Adam Parkin
8. März 2013 um 16:45 Uhr
@SeanPatrickFloyd Jetzt, wo Java 8 herauskommt, möchten Sie dies mit einem Beispiel mit Lambdas aktualisieren? Wie Collections2.transform(input -> Integer.toHexString(intput.intValue())
– Daniel Lubarov
4. April 2014 um 19:41 Uhr
@Daniel In Java 8 sehe ich keinen Grund, dies mit Guava zu tun. Stattdessen würde ich mich für Leventovs Antwort entscheiden
– Sean Patrick Floyd
5. April 2014 um 9:48 Uhr
Es gibt eine wunderbare Bibliothek namens Funktionales Java das viele der Dinge handhabt, die Java haben sollte, aber es nicht tut. Andererseits gibt es auch diese wunderbare Sprache Scala, die alles tut, was Java hätte tun sollen, aber dennoch nicht mit irgendetwas kompatibel ist, das für die JVM geschrieben wurde.
Mich interessiert, wie sie die folgende Syntax aktiviert haben: a.map({int i => i + 42});
haben sie den Compiler erweitert? oder Präprozessor hinzugefügt?
– Andrej
11. Oktober 2010 um 15:07 Uhr
@Andrey – Sie können sie das entweder selbst fragen oder sich den Quellcode ansehen, um zu sehen, wie es gemacht wird. Hier ist ein Link zur Quelle: Functionaljava.org/source
– Weizen
11. Oktober 2010 um 15:09 Uhr
@Andrey: Beispiele verwenden die Syntax aus dem BGGA-Schließungsvorschlag. Obwohl es einen laufenden Prototyp gibt, ist er noch nicht in “offiziellem” Java.
– Peter Stibraný
11. Oktober 2010 um 15:10 Uhr
@Andrey: Diese Syntax ist Teil einer vorgeschlagenen Spezifikation für Closures in Java (siehe vorletzter Absatz auf der Homepage). Es gibt nur eine prototypische Umsetzung.
– Michael Borgwardt
11. Oktober 2010 um 15:12 Uhr
Scala-Thread-Hijacking 🙁 Ich hoffe, SO wird nicht wie die JavaPosse-Mailingliste 😉
– Jörn
11. Oktober 2010 um 15:13 Uhr
Emmanuel Tuzery
Seien Sie sehr vorsichtig mit Collections2.transform()
aus Guave. Der größte Vorteil dieser Methode ist gleichzeitig ihre größte Gefahr: ihre Faulheit.
Schauen Sie sich die Dokumentation von an Lists.transform()
was meiner Meinung nach auch gilt Collections2.transform()
:
Die Funktion wird träge angewendet und bei Bedarf aufgerufen. Dies ist notwendig, damit die zurückgegebene Liste eine Ansicht ist, aber es bedeutet, dass die Funktion viele Male für Massenoperationen wie List.contains(java.lang.Object) und List.hashCode() angewendet wird. Damit dies gut funktioniert, sollte die Funktion schnell sein. Um eine verzögerte Auswertung zu vermeiden, wenn die zurückgegebene Liste keine Ansicht sein muss, kopieren Sie die zurückgegebene Liste in eine neue Liste Ihrer Wahl.
Auch in der Dokumentation von Collections2.transform()
Sie erwähnen, dass Sie eine Live-Ansicht erhalten, dass sich Änderungen in der Quellliste auf die transformierte Liste auswirken. Diese Art von Verhalten kann zu schwer zu verfolgenden Problemen führen, wenn der Entwickler nicht erkennt, wie es funktioniert.
Wenn Sie eine klassischere “Karte” wollen, die nur einmal läuft, dann sind Sie mit besser dran FluentIterable
, ebenfalls aus Guava, dessen Bedienung viel einfacher ist. Hier ist das Google-Beispiel dafür:
FluentIterable
.from(database.getClientList())
.filter(activeInLastMonth())
.transform(Functions.toStringFunction())
.limit(10)
.toList();
transform()
Hier ist die Kartenmethode. Es verwendet die gleiche Funktion <> “Rückrufe” wie Collections.transform()
. Die Liste, die Sie zurückerhalten, ist jedoch schreibgeschützt, verwenden Sie copyInto()
um eine Lese-Schreib-Liste zu erhalten.
Andernfalls ist dies natürlich veraltet, wenn Java8 Lambdas herausbringt.
Dies ist eine weitere funktionale Bibliothek, mit der Sie map verwenden können: http://code.google.com/p/totallylazy/
sequence(1, 2).map(toString); // lazily returns "1", "2"
Hier ist eine Anleitung zur Verwendung von TotallyLazy: intrepidis.blogspot.com/2013/07/…
– unerschrocken
11. Juli 2013 um 20:34 Uhr
Obwohl es eine alte Frage ist, möchte ich eine andere Lösung zeigen:
Definieren Sie einfach Ihre eigene Operation mit Java-Generika und Java 8-Streams:
public static <S, T> List<T> map(Collection<S> collection, Function<S, T> mapFunction) {
return collection.stream().map(mapFunction).collect(Collectors.toList());
}
Dann können Sie Code wie folgt schreiben:
List<String> hex = map(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);
Hier ist eine Anleitung zur Verwendung von TotallyLazy: intrepidis.blogspot.com/2013/07/…
– unerschrocken
11. Juli 2013 um 20:34 Uhr
Dupliziert (eher besser) unter stackoverflow.com/questions/3907412/…
– Cholett
11. Oktober 2010 um 15:03 Uhr
@Chris: Wie ist es die gleiche Frage?
– Albert
11. Oktober 2010 um 15:12 Uhr
Es ist nicht dieselbe Frage. Es hängt aber eng zusammen…
– Jörn
11. Oktober 2010 um 15:12 Uhr
Wenn die Antwort auf diese Frage ja lautet, beantwortet sie auch die andere verknüpfte Frage. Wenn die Antwort nein ist (und es scheint so), sind sie völlig unabhängig.
– Albert
11. Oktober 2010 um 15:17 Uhr
Ab Java8 könnte sich @delnan darauf bezogen haben leveluplunch.com/java/examples/…
– Ewiger Code
13. Juni 2017 um 20:49 Uhr