Para limpar uma lista de dados, criei um método que aceita a lista de dados e a lista de operações de limpeza a serem executadas.
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;
}
O problema aqui é que estamos criando a lista inteira novamente, pois Collectors.toList()
retorna uma nova lista. Podemos alcançar o mesmo resultado sem usar o espaço extra?
Abaixo está o código para chamada:
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
fonte
fonte
toList()
retorna umCollector
não umList
, e não: você não pode ter "dados extra" sem "espaço extra"Respostas:
Se a modificação da lista no local for permitida, você poderá usar
andThen
combina duasFunction
instâncias e se pelo menos uma funçãocleanOps
estiver presente, ou seja, a lista não estiver vazia, a função combinada resultante será aplicada a todos os elementos da lista e os elementos substituídos pelo resultado, usandoreplaceAll
.Infelizmente,
replaceAll
requer umUnaryOperator<T>
e não umFunction<T,T>
, apesar de ser funcionalmente equivalente, por isso temos que usar o adaptadorf::apply
.Como esses tipos de função são equivalentes, poderíamos alterar a lista para
List<UnaryOperator<T>>
, mas precisamos enfrentar o fato de que não háandThen
implementação especializada paraUnaryOperator
, portanto, precisaríamos de:A fonte do chamador muda para
então.
Como uma observação lateral, não há necessidade de uma construção como
como o
toString()
método de aList
produz exatamente a mesma saída. Como oprintln(Object)
método chamatoString()
implicitamente, você pode apenas usarfonte
Parece que você precisa usar
List.replaceAll()
, que substitui cada elemento desta lista pelo resultado da aplicação do operador fornecido a esse elemento.Eu renomearia o método, já que é genérico, portanto não necessariamente processa um
List
deString
s.fonte