Java8:一次性应用流映射和过滤器
我正在用Java8为一个文件编写解析器。使用Java8:一次性应用流映射和过滤器,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我正在用Java8为一个文件编写解析器。使用Files.lines读取文件,并返回顺序流 每一行都映射到一个数据对象结果,如下所示: Result parse(String _line) { // ... code here Result _result = new Result(). if (/* line is not needed */) { return null; } else { /* parse line into result */ retu
Files.lines
读取文件,并返回顺序流
每一行都映射到一个数据对象结果
,如下所示:
Result parse(String _line) {
// ... code here
Result _result = new Result().
if (/* line is not needed */) {
return null;
} else {
/* parse line into result */
return _result;
}
}
现在,我们可以将流中的每一行映射到其相应的结果:
public Stream<Result> parseFile(Path _file) {
Stream<String> _stream = Files.lines(_file);
Stream<Result> _resultStream = _stream.map(this::parse);
}
如我在
parseLine/\u stream.map中所知,如果需要结果,如何组合map/filter操作?如注释中所述,流将在一次过程中处理,因此实际上不需要更改任何内容。您可以使用flatMap
并让parse
返回流:
Stream<Result> parse(String _line) {
.. code here
Result _result = new Result().
if (/* line is not needed */) {
return Stream.empty();
} else {
/** parse line into result */
return Stream.of(_result);
}
}
public Stream<Result> parseFile(Path _file) {
return Files.lines(_file)
.flatMap(this::parse);
}
流解析(字符串_行){
…这里是代码
结果_Result=新结果()。
如果(/*行不需要*/){
返回Stream.empty();
}否则{
/**将行解析为结果*/
返回流。of(_结果);
}
}
公共流解析文件(路径_文件){
返回文件。行(_文件)
.flatMap(this::parse);
}
这样一来,您首先就不会有任何null
值。针对Java 9的更新:
使用Stream
似乎是parse()
函数的错误返回类型。一个流可以包含很多很多值,因此parse()
的用户要么假设流中最多有一个值,要么使用collect
之类的方法提取并使用parse()
操作的结果。如果函数和它的用法只被几行代码隔开,这可能没问题,但是如果距离增加了,比如在一个完全不同的JUnit测试文件中,接口契约与返回值之间就不清楚了
与其返回流
,不如在不需要行时返回空的可选
Optional<Result> parse(String _line) {
... code here
Result _result = null;
if (/* line needed */) {
/** parse line into result */
}
return Optional.ofNullable(_result);
}
将可选
值流转换为结果
值流,不带任何空选项 我不明白,returnfiles.line(_file).map(this::parse).filter(v->v!=null)有什么问题代码>?仅当您使用需要完全迭代的终端操作(例如forEach、collect、reduce)时,才会在一次运行中处理流。@user3001另请参见:您关于多个过程的假设不正确。过滤和映射在单个过程中处理。(通常,整个管道在一次过程中处理,除非有排序等操作必须在生成任何数据之前查看所有数据。)在这种情况下,您将把map&filter
替换为map&flatMap
。直接使用null
然后将其过滤掉没有多大区别。
Optional<Result> parse(String _line) {
... code here
Result _result = null;
if (/* line needed */) {
/** parse line into result */
}
return Optional.ofNullable(_result);
}
public Stream<Result> parseFile(Path _file) {
return Files.lines(_file)
.map(this::parse)
.flatMap(Optional::stream)
}