Pour nettoyer une liste de données, j'ai créé une méthode qui accepte la liste des données et la liste des opérations de nettoyage à effectuer.
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;
}
Le problème ici est que nous créons à nouveau la liste entière comme Collectors.toList()
renvoie une nouvelle liste. Pouvons-nous obtenir le même résultat sans utiliser l'espace supplémentaire?
Voici le code d'invocation:
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
la source
la source
toList()
renvoie unCollector
pas unList
, et non: vous ne pouvez pas avoir de "données supplémentaires" sans "espace supplémentaire"Réponses:
Si la modification de la liste sur place est autorisée, vous pouvez utiliser
andThen
combine deuxFunction
instances et si au moins une fonction était présente, c'est-à-dire que lacleanOps
liste n'est pas vide, la fonction combinée résultante sera appliquée à tous les éléments de la liste et aux éléments remplacés par le résultat, en utilisantreplaceAll
.Malheureusement,
replaceAll
nécessite unUnaryOperator<T>
plutôt qu'unFunction<T,T>
, bien qu'il soit fonctionnellement équivalent, nous devons donc utiliser l'adaptateurf::apply
.Étant donné que ces types de fonctions sont équivalents, nous pourrions changer la liste en
List<UnaryOperator<T>>
, mais nous devons faire face au fait qu'il n'y a pas d'andThen
implémentation spécialisée pourUnaryOperator
, nous aurions donc besoin de:La source de l'appelant devient
puis.
En remarque, il n'y a pas besoin d'une construction comme
car la
toString()
méthode de aList
produit exactement la même sortie. Comme laprintln(Object)
méthode appelletoString()
implicitement, vous pouvez simplement utiliserla source
Il semble que vous deviez utiliser
List.replaceAll()
, ce qui remplace chaque élément de cette liste par le résultat de l'application de l'opérateur donné à cet élément.Je renommerais la méthode, cependant, car elle est générique, donc elle ne traite pas nécessairement l'une
List
desString
s.la source