Para limpiar una lista de datos, he creado un método que acepta la lista de datos y la lista de operaciones de limpieza a realizar.
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;
}
El problema aquí es que estamos creando toda la lista nuevamente, ya que Collectors.toList()
devuelve una nueva lista. ¿Podemos lograr el mismo resultado sin usar el espacio extra?
A continuación se muestra el código de invocación:
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
fuente
fuente
toList()
devuelve unCollector
no aList
, y no: no puede tener "datos adicionales" sin "espacio adicional"Respuestas:
Si se permite modificar la lista en el lugar, puede usar
andThen
combina dosFunction
instancias y si al menos una función estaba presente, es decir, lacleanOps
lista no está vacía, la función combinada resultante se aplicará a todos los elementos de la lista y los elementos reemplazados por el resultado, utilizandoreplaceAll
.Desafortunadamente,
replaceAll
requiere un enUnaryOperator<T>
lugar de unFunction<T,T>
, a pesar de ser funcionalmente equivalente, por lo que tenemos que usar el adaptadorf::apply
.Dado que estos tipos de funciones son equivalentes, podríamos cambiar la lista a
List<UnaryOperator<T>>
, pero luego, tenemos que enfrentar el hecho de que no hay unaandThen
implementación especializadaUnaryOperator
, por lo que necesitaríamos:La fuente de la persona que llama cambia a
entonces.
Como nota al margen, no hay necesidad de una construcción como
como el
toString()
método de aList
produce exactamente la misma salida. Como elprintln(Object)
método llamatoString()
implícitamente, solo puede usarfuente
Parece que necesita usar
List.replaceAll()
, que reemplaza cada elemento de esta lista con el resultado de aplicar el operador dado a ese elemento.Sin embargo, cambiaría el nombre del método, ya que es genérico, por lo que no necesariamente procesa una
List
deString
s.fuente