java - 将流中的 2 个对象映射到单个第三个对象?
问题描述
如果我有要转换的对象的时间戳列表和文件路径,我可以制作一组期望方法签名的转换器Converter(filePath, start, end)
吗?
更多细节(伪代码):
一些有时间戳的列表(想象一下它们以秒为单位)path = somewhere
,,,list = {0, 15, 15, 30}
我怎么能做这样的事情:list.stream。魔术.map(start, end -> new Converter (path, start, end))?
结果:new Converter (path, 0, 15), new Converter(path, 15, 30)
注意:我知道BiFunction
,但据我所知,流没有实现它。
解决方案
有许多方法可以使用流获得所需的结果。
但首先,您不必使用 Stream API
,如果要处理包含数十个和数百个元素的列表,我建议您使用普通的旧列表迭代。
例如尝试下面的代码示例。
我们很容易看到由流的性质引起的两个表面问题以及它们与将其元素配对的想法的不相容性:
- 有必要应用有状态的函数,这在使用中真的很棘手,
map()
应该被认为是脏编码;并且映射会在应该正确过滤掉的偶数地方产生一些空值; - 当流包含奇数个元素时就会出现问题,而您永远无法预测它是否存在。
如果您决定使用流,那么为了清楚地说明我们需要 Iterator、Spliterator 或 Collector 的自定义实现 - 取决于需求。无论如何,有几个不明显的极端情况你不会乐意自己实现,所以可以尝试大量的第三方流库。最流行的两个是Streamex和RxJava。他们肯定有配对流元素的工具......但不要忘记检查您的案例的性能!
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Stream;
public class Sample
{
public static void main(String... arg)
{
String path = "somewhere";
Stream<Converter> stream = Stream.of(0, 15, 25, 30).map(
new Function<Integer, Converter>()
{
int previous;
boolean even = true;
@Override
public Converter apply(Integer current)
{
Converter converter = even ? null : new Converter(path, previous, current);
even = !even;
previous = current;
return converter;
}
}).filter(Objects::nonNull);
stream.forEach(System.out::println);
}
static class Converter
{
private final String path;
private final int start;
private final int end;
Converter(String path, int start, int end)
{
this.path = path;
this.start = start;
this.end = end;
}
public String toString()
{
return String.format("Converter[%s,%s,%s]", path, start, end);
}
}
}
推荐阅读
- java - Spring security 多个 Http 配置 - 仅顺序(1)有效
- ios - 我可以提交在非 IOS 设备(例如,使用 VMware 或任何其他方式)或没有 MacBook 上创建的 IOS 应用程序吗?
- reactjs - 如何使用 Relay、GraphQL 和 React 渲染数据
- java - 是否可以通过自定义键盘应用程序跟踪在任何应用程序的文本字段中输入的整个字符串?
- get - GoogleSignIn.getClient(this, gso) 不存在
- css - Flexbox 布局与 Safari 中的 grid-column-gap 不兼容
- python - For 循环使用 Jinja 和 PyMongo 为整个 dict 重复相同的输出
- machine-learning - LSTM 在更高的验证损失下具有更高的验证精度(Python:Keras)
- node.js - Nodemailer - 错误:连接 ETIMEDOUT 216.58.221.36:587
- connection-pooling - 在 Spring 上使用池连接工厂和 Artemis ActiveMQ 故障转移来处理重新发送消息