Java: Gibt es eine Map-Funktion?
-
29-09-2019 - |
Lösung
Es gibt keinen Begriff eine Funktion im JDK als Java 6.
Guava hat eine Funktion Schnittstelle obwohl und die
Collections2.transform(Collection<E>, Function<E,E2>)
Methode bietet die Funktionalität, die Sie benötigen.
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);
Ausgang:
[a, 14, 1e, 28, 32]
In diesen Tagen, mit Java 8, gibt es tatsächlich eine Map-Funktion, so dass ich wahrscheinlich den Code in prägnanter Weise schreiben würde:
Collection<String> hex = input.stream()
.map(Integer::toHexString)
.collect(Collectors::toList);
Andere Tipps
Da Java 8, gibt es einige Standardoptionen dies in JDK zu tun:
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());
Siehe java.util.Collection.stream()
und java.util.stream.Collectors.toList()
.
Es gibt eine wunderbare Bibliothek Functional Java genannt, die viele der Dinge behandelt würden Sie Java haben wollen, aber es nicht. Dann wieder gibt es auch diese wunderbare Sprache Scala, die alles tut Java getan haben sollte, aber nicht während immer noch mit etwas für die JVM geschrieben kompatibel ist.
Seien Sie sehr vorsichtig mit Collections2.transform()
von Guave.
Dass größte Vorteil der Methode ist auch die größte Gefahr. Seine Faulheit
Sehen Sie in der Dokumentation von Lists.transform()
, die ich glaube, gilt auch für Collections2.transform()
:
Die Funktion wird träge angewandt, aufgerufen, wenn nötig. Das ist notwendig für die zurückgegebene Liste eine Ansicht sein, aber es bedeutet, dass die Funktion wird oft für Bulk-Operationen angewendet wie List.contains (java.lang.Object) und List.hashCode (). Für diese zu eine gute Leistung, sollte Funktion schnell sein. Um zu vermeiden, lazy evaluation, wenn die zurückgegebene Liste muss nicht eine Ansicht, kopieren Sie die zurückgegebene Liste sein in eine neue Liste Ihrer Wahl.
Auch in der Dokumentation von Collections2.transform()
sie erwähnen Sie eine Live-Ansicht zu bekommen, dass Veränderungen in der Quellenliste wirken sich auf die transformierten Liste. Diese Art von Verhalten zu schwer zu Spur Problemen führen kann, wenn der Entwickler nicht erkennen, wie es funktioniert.
Wenn Sie eine klassische „Karte“ wollen, die einmal ausgeführt werden und nur einmal, dann bist du besser dran mit FluentIterable
, auch von Guava, die einen Betrieb hat, die 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 Karte Methode. Es verwendet die gleiche Funktion <> „Callbacks“ als Collections.transform()
. Die Liste, die Sie zurückbekommen schreibgeschützt ist allerdings Verwendung copyInto()
eine Schreib-Lese-Liste zu erhalten.
Ansonsten natürlich, wenn java8 mit lambda kommt, wird diese veraltet sein.
Dies ist eine weitere funktionelle lib mit dem Sie Karte verwenden: http://code.google.com / p / totallylazy /
sequence(1, 2).map(toString); // lazily returns "1", "2"
Auch wenn es eine alte Frage ist würde Ich mag eine andere Lösung zeigen:
Just definieren Sie Ihren eigenen Betrieb mit Java Generika und Java 8 Streams:
public static <S, T> List<T> mapAll(Collection<S> collection, Function<S, T> mapper) {
return collection.stream().map(mapper).collect(Collectors.toList());
}
Als Sie Code wie diesen schreiben können:
List<String> hex = mapAll(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);