java - 在 Java8 中清理数据列表
问题描述
为了清理数据列表,我创建了一个接受数据列表和要执行的清理操作列表的方法。
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()));
}
解决方案
如果允许就地修改列表,您可以使用
public <T> List<T> cleanData(List<T> data, List<Function<T, T>> cleanOps) {
cleanOps.stream().reduce(Function::andThen).ifPresent(f -> data.replaceAll(f::apply));
return data;
}
andThen
组合两个Function
实例,如果至少存在一个函数,即cleanOps
列表不为空,则生成的组合函数将应用于所有列表元素和被结果替换的元素,使用replaceAll
.
不幸的是,replaceAll
需要 aUnaryOperator<T>
而不是 a Function<T,T>
,尽管在功能上是等效的,所以我们必须使用适配器f::apply
。
由于这些函数类型是等价的,我们可以将列表更改为List<UnaryOperator<T>>
,但是,我们必须面对一个事实,即没有专门andThen
的实现UnaryOperator
,所以我们需要:
public <T> List<T> cleanData(List<T> data, List<UnaryOperator<T>> cleanOps) {
cleanOps.stream()
.reduce((f1,f2) -> t -> f2.apply(f1.apply(t)))
.ifPresent(data::replaceAll);
return data;
}
调用者的源更改为
List<UnaryOperator<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(cleanData(data, cleanOps));
然后。
作为旁注,不需要像这样的构造
System.out.println(Arrays.toString(cleanData(data, cleanOps).toArray()));
因为 a 的toString()
方法List
产生完全相同的输出。由于该println(Object)
方法隐式调用toString()
,您可以使用
System.out.println(cleanData(data, cleanOps));
推荐阅读
- php - PHP获取最后一个特定日期
- apache-spark - 无法在 MacOS 中将 Python 3 设置为 Apache spark 的默认版本
- python - Keras如何将输入形状更改为3维
- xamarin - 如何更改
- css - 创建两个垂直按钮反应原生
- python - 在 Windows 10 和虚拟机 Ubuntu 中获得相同操作的不同结果
- docker - 尝试在 Windows 10 上到达 Docker Express API 端点的连接重置错误
- ruby - bundle 在安装 dradis 社区版时抛出错误
- javascript - 如何在 puppeteer page.evaluate 中使用 url 模块
- python - python脚本后没有打印,没有错误