Java Sammlung / map Verfahren gleichwertig gelten?
-
09-09-2019 - |
Frage
Ich möchte eine Funktion auf eine Java-Sammlung anzuwenden, in diesem speziellen Fall eine Karte. Gibt es eine schöne Möglichkeit, dies zu tun? Ich habe eine Karte und möchte nur laufen trim () auf alle Werte in der Karte und haben die Karte, um die Updates zu reflektieren.
Lösung
Mit Java 8 des Lambda, das ist ein Motto:
map.replaceAll((k, v) -> v.trim());
Aus Gründen der Geschichte, hier ist eine Version ohne Lambda-Ausdrücke:
public void trimValues(Map<?, String> map) {
for (Map.Entry<?, String> e : map.entrySet()) {
String val = e.getValue();
if (val != null)
e.setValue(val.trim());
}
}
oder allgemeiner:
interface Function<T> {
T operate(T val);
}
public static <T> void replaceValues(Map<?, T> map, Function<T> f)
{
for (Map.Entry<?, T> e : map.entrySet())
e.setValue(f.operate(e.getValue()));
}
Util.replaceValues(myMap, new Function<String>() {
public String operate(String val)
{
return (val == null) ? null : val.trim();
}
});
Andere Tipps
Ich weiß nicht, einen Weg zu tun, dass mit dem JDK-Bibliotheken anderer als der akzeptierte Antwort, aber Google Kollektionen können Sie das Folgende tun, mit dem Klassen com.google.collect.Maps
und com.google.common.base.Function
:
Map<?,String> trimmedMap = Maps.transformValues(untrimmedMap, new Function<String, String>() {
public String apply(String from) {
if (from != null)
return from.trim();
return null;
}
}
Der größte Unterschied dieses Verfahren mit dem vorgeschlagenen ist, dass es einen Blick auf Ihre Original-Karte bietet, was bedeutet, dass, während es immer synchron mit dem Original-Karte ist, könnte die apply
Methode oft aufgerufen werden, wenn Sie Manipulieren der stark kartieren.
Eine ähnliche Collections2.transform(Collection<F>,Function<F,T>)
Methode existiert für Sammlungen.
Ob Sie Ihre Sammlung an Ort und Stelle ändern können oder nicht, hängt von der Klasse der Objekte in der Sammlung.
Wenn diese Objekte sind unveränderlich (die Strings sind), dann können Sie nicht nehmen Sie nur die Elemente aus der Sammlung und modifizieren - stattdessen müssen Sie über die Sammlung iterieren, rufen Sie die entsprechende Funktion, und setzen Sie dann die resultierende Wert zurück.
Könnte Overkill für so etwas, aber es gibt eine Reihe von wirklich guten Programmen für diese Art von Problemen in der Jakarta Commons-Kochbuch von O'Reilly .
ich am Ende mit einer Mutation von @ Erickson Antwort, mutiert:
- Rückkehr eine neue
Collection
, ändern nicht an Ort und Stelle - Rückkehr
Collection
s mit Elementen des Typs gleich den Rückgabetyp derFunction
- Unterstützung Mapping entweder über den Werten einer Karte oder die Elemente einer Liste
Code:
public static interface Function<L, R> {
L operate(R val);
}
public static <K, L, R> Map<K, L> map(Map<K, R> map, Function<L, R> f) {
Map<K, L> retMap = new HashMap<K, L>();
for (Map.Entry<K, R> e : map.entrySet()) retMap.put(e.getKey(), f.operate(e.getValue()));
return retMap;
}
public static <L, R> List<L> map(List<R> list, Function<L, R> f) {
List<L> retList = new ArrayList<L>();
for (R e : list) retList.add(f.operate(e));
return retList;
}
Sie werden über alle Einträge durchlaufen müssen und jeden String-Wert trimmen. Da String unveränderlich ist haben Sie es in der Karte neu zu setzen. Ein besserer Ansatz könnte sein, die Werte zu trimmen, wie sie in der Karte platziert sind.
Ich habe mit einer "Mapper" Klasse kommen
public static abstract class Mapper<FromClass, ToClass> {
private Collection<FromClass> source;
// Mapping methods
public abstract ToClass map(FromClass source);
// Constructors
public Mapper(Collection<FromClass> source) {
this.source = source;
}
public Mapper(FromClass ... source) {
this.source = Arrays.asList(source);
}
// Apply map on every item
public Collection<ToClass> apply() {
ArrayList<ToClass> result = new ArrayList<ToClass>();
for (FromClass item : this.source) {
result.add(this.map(item));
}
return result;
}
}
Dass ich so verwenden:
Collection<Loader> loaders = new Mapper<File, Loader>(files) {
@Override public Loader map(File source) {
return new Loader(source);
}
}.apply();
Sie können auch einen Blick auf Google Kollektionen nehmen