Для очистки списка данных я создал метод, который принимает список данных и список операций очистки, которые необходимо выполнить.
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;
}
Проблема в том, что мы снова создаем весь список, так как он Collectors.toList()
возвращает новый список. Можем ли мы достичь того же результата без использования дополнительного пространства?
Ниже приведен код для вызова:
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
Дхармвир Тивари
источник
источник
toList()
возвращаетCollector
not, aList
и no: вы не можете иметь «лишние данные» без «лишнего пробела»Ответы:
Если изменение списка на месте разрешено, вы можете использовать
andThen
объединяет дваFunction
экземпляра и, если хотя бы одна функция присутствовала, т.е.cleanOps
список не пуст, результирующая объединенная функция будет применена ко всем элементам списка и элементам, замененным результатом, используяreplaceAll
.К сожалению,
replaceAll
требуется,UnaryOperator<T>
а неFunction<T,T>
, несмотря на то, что функционально эквивалентны, поэтому мы должны использовать адаптерf::apply
.Поскольку эти типы функций эквивалентны, мы могли бы изменить список на
List<UnaryOperator<T>>
, но тогда мы должны столкнуться с тем фактом, что не существует специализированнойandThen
реализации дляUnaryOperator
, поэтому нам потребуется:Источник звонка меняется на
тогда.
В качестве примечания, нет необходимости в такой конструкции, как
так как
toString()
методList
производит точно такой же результат. Посколькуprintln(Object)
метод вызываетtoString()
неявно, вы можете просто использоватьисточник
Похоже, вам нужно использовать
List.replaceAll()
, который заменяет каждый элемент этого списка с результатом применения данного оператора к этому элементу.Однако я бы переименовал метод, поскольку он универсальный, поэтому не обязательно обрабатывает a
List
ofString
s.источник