Do czyszczenia listy danych stworzyłem metodę, która akceptuje listę danych i listę operacji czyszczenia do wykonania.
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;
}
Problem polega na tym, że ponownie tworzymy całą listę, ponieważ Collectors.toList()
zwraca nową listę. Czy możemy osiągnąć ten sam wynik bez korzystania z dodatkowej przestrzeni?
Poniżej znajduje się kod wywołania:
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
źródło
źródło
toList()
zwraca aCollector
nieList
i nie: nie możesz mieć „dodatkowych danych” bez „dodatkowej przestrzeni”Odpowiedzi:
Jeśli modyfikowanie listy w miejscu jest dozwolone, możesz użyć
andThen
łączy dwaFunction
wystąpienia i jeśli obecnacleanOps
jest co najmniej jedna funkcja, tj. lista nie jest pusta, wynikowa połączona funkcja zostanie zastosowana do wszystkich elementów listy i elementów zastąpionych przez wynik, przy użyciureplaceAll
.Niestety
replaceAll
wymagaUnaryOperator<T>
raczej niżFunction<T,T>
, mimo że jest funkcjonalnie równoważny, więc musimy użyć adapteraf::apply
.Ponieważ te typy funkcji są równoważne, moglibyśmy zmienić listę na
List<UnaryOperator<T>>
, ale wtedy musimy zmierzyć się z faktem, że nie ma specjalnejandThen
implementacjiUnaryOperator
, więc potrzebowalibyśmy:Źródło dzwoniącego zmienia się na
następnie.
Na marginesie, nie ma takiej potrzeby
ponieważ
toString()
metoda aList
daje dokładnie takie same wyniki. Ponieważprintln(Object)
metoda wywołujetoString()
niejawnie, możesz po prostu użyćźródło
Wygląda na to, że musisz użyć
List.replaceAll()
, który zastępuje każdy element tej listy wynikiem zastosowania danego operatora do tego elementu.Chciałbym zmienić nazwę metody, chociaż, ponieważ jest to ogólny, więc nie musi przetwarzać
List
zString
s.źródło