gpt4 book ai didi

java - 如何使用 java.util.stream 处理文件 block

转载 作者:行者123 更新时间:2023-11-30 09:01:15 25 4
gpt4 key购买 nike

为了熟悉流 api,我尝试编写一个非常简单的模式。

问题:有一个文本文件不包含嵌套的文本 block 。所有 block 都由开始/结束模式标识(例如 <start><stop> 。 block 的内容在语法上无法与 block 之间的噪声区分开来。因此,使用简单(无状态)lambda 是不可能的。

我只能实现一些丑陋的东西,比如:
Files.lines(path).collect(new MySequentialParseAndProsessEachLineCollector<>());
老实说,这不是我想要的。

我正在寻找类似这样的映射器:
Files.lines(path).map(MyMapAllLinesOfBlockToBuckets()).parallelStream().collect(new MyProcessOneBucketCollector<>());

is there a good way to extract chunks of data from a java 8 stream似乎包含解决方案的骨架。不幸的是,我愚蠢地将其转化为我的问题。 ;-)

有什么提示吗?

最佳答案

这是一个可用于转换 Stream<String> 的解决方案,每个元素代表一行,到 Stream<List<String>> ,每个元素代表使用指定分隔符找到的 block :

public class ChunkSpliterator implements Spliterator<List<String>> {
private final Spliterator<String> source;
private final Predicate<String> start, end;
private final Consumer<String> getChunk;
private List<String> current;

ChunkSpliterator(Spliterator<String> lineSpliterator,
Predicate<String> chunkStart, Predicate<String> chunkEnd) {
source=lineSpliterator;
start=chunkStart;
end=chunkEnd;
getChunk=s -> {
if(current!=null) current.add(s);
else if(start.test(s)) current=new ArrayList<>();
};
}
public boolean tryAdvance(Consumer<? super List<String>> action) {
while(current==null || current.isEmpty()
|| !end.test(current.get(current.size()-1)))
if(!source.tryAdvance(getChunk)) return false;
current.remove(current.size()-1);
action.accept(current);
current=null;
return true;
}
public Spliterator<List<String>> trySplit() {
return null;
}
public long estimateSize() {
return Long.MAX_VALUE;
}
public int characteristics() {
return ORDERED|NONNULL;
}

public static Stream<List<String>> toChunks(Stream<String> lines,
Predicate<String> chunkStart, Predicate<String> chunkEnd,
boolean parallel) {

return StreamSupport.stream(
new ChunkSpliterator(lines.spliterator(), chunkStart, chunkEnd),
parallel);
}
}

匹配谓词的行不包含在 block 中;如果需要,很容易改变这种行为。

可以这样使用:

ChunkSpliterator.toChunks( Files.lines(Paths.get(myFile)),
Pattern.compile("^<start>$").asPredicate(),
Pattern.compile("^<stop>$").asPredicate(),
true )
.collect(new MyProcessOneBucketCollector<>())

模式指定为 ^word$要求整行仅包含单词;没有这些 anchor ,包含模式的行可以开始和结束一个 block 。源流的性质在创建 block 时不允许并行,因此当与立即收集操作链接时,整个操作的并行性相当有限。这取决于 MyProcessOneBucketCollector是否存在任何并行性。

如果您的最终结果不依赖于源文件中桶的出现顺序,强烈建议您的收集器报告自己为 UNORDERED 或者你插入 unordered() collect 之前的流方法链中.

关于java - 如何使用 java.util.stream 处理文件 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26463771/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com