Zum Bereinigen einer Datenliste habe ich eine Methode erstellt, die die Liste der Daten und die Liste der durchzuführenden Reinigungsvorgänge akzeptiert.
public <T> List<T> cleanData(List<T> data, List<Function<T, T>> cleanOps) {
List<T>dataNew=data.stream().map((str) -> {
T cleanData = str;
for(Function<T,T> function:cleanOps) {
cleanData=function.apply(cleanData);
}
return cleanData;
}).collect(Collectors.toList());
return dataNew;
}
Das Problem hierbei ist, dass wir die gesamte Liste erneut erstellen, da Collectors.toList()
eine neue Liste zurückgegeben wird. Können wir das gleiche Ergebnis erzielen, ohne den zusätzlichen Platz zu nutzen?
Unten ist der Code für den Aufruf:
public void processData() {
List<Function<String, String>> cleanOps = new ArrayList<>();
cleanOps.add(String::toLowerCase);
cleanOps.add(str -> str.replaceAll(" ", ""));
List<String> data = new ArrayList<>();
data.add("John Doe");
data.add("Jane Doe");
System.out.println(Arrays.toString(cleanData(data, cleanOps).toArray()));
}
java
java-8
functional-programming
java-stream
Dharmvir Tiwari
quelle
quelle
toList()
gibt einCollector
nicht einList
und nein zurück: Sie können keine "zusätzlichen Daten" ohne "zusätzlichen Speicherplatz" habenAntworten:
Wenn das Ändern der Liste an Ort und Stelle zulässig ist, können Sie verwenden
andThen
kombiniert zweiFunction
Instanzen und wenn mindestens eine Funktion vorhanden war, dh diecleanOps
Liste nicht leer ist, wird die resultierende kombinierte Funktion auf alle Listenelemente angewendet und die durch das Ergebnis ersetzten Elemente mitreplaceAll
.Leider
replaceAll
erfordert einUnaryOperator<T>
eher als einFunction<T,T>
, obwohl es funktional gleichwertig ist, so dass wir den Adapter verwenden müssenf::apply
.Da diese Funktionstypen äquivalent sind, könnten wir die Liste in ändern
List<UnaryOperator<T>>
, aber dann müssen wir uns der Tatsache stellen, dass es keine spezielleandThen
Implementierung für gibtUnaryOperator
, also müssten wir:Die Quelle des Anrufers ändert sich zu
dann.
Nebenbei bemerkt, es besteht keine Notwendigkeit für ein Konstrukt wie
da die
toString()
Methode von aList
genau die gleiche Ausgabe erzeugt. Da dieprintln(Object)
MethodetoString()
implizit aufruft , können Sie einfach verwendenquelle
Es sieht so aus, als müssten Sie verwenden
List.replaceAll()
, wodurch jedes Element dieser Liste durch das Ergebnis der Anwendung des angegebenen Operators auf dieses Element ersetzt wird.Ich würde die Methode jedoch umbenennen, da sie generisch ist und daher nicht unbedingt ein
List
vonString
s verarbeitet.quelle