Java中的有限生成流-如何创建一个?
在Java中,可以使用Java中的有限生成流-如何创建一个?,java,java-8,java-stream,Java,Java 8,Java Stream,在Java中,可以使用stream.generate(supplier)轻松生成无限流。但是,我需要生成一个最终将完成的流 例如,想象一下,我想要一个目录中所有文件的流。文件的数量可能很大,因此我无法预先收集所有数据并从中创建流(通过collection.stream())。我需要逐段生成序列。但是流显然会在某个时刻结束,像(collect()或findAny())这样的终端操作员需要处理它,因此stream.generate(supplier)在这里不合适 在Java中有没有合理的简单方法可以
stream.generate(supplier)
轻松生成无限流。但是,我需要生成一个最终将完成的流
例如,想象一下,我想要一个目录中所有文件的流。文件的数量可能很大,因此我无法预先收集所有数据并从中创建流(通过collection.stream()
)。我需要逐段生成序列。但是流显然会在某个时刻结束,像(collect()
或findAny()
)这样的终端操作员需要处理它,因此stream.generate(supplier)
在这里不合适
在Java中有没有合理的简单方法可以做到这一点,而不必自己实现整个流接口
我可以想到一个简单的破解方法——使用无限Stream.generate(supplier)
,并在获取所有实际值时提供null或抛出异常。但是它会破坏标准的流操作符,我只能在我自己的操作符知道这种行为的情况下使用它
澄清
评论中的人向我推荐takeWhile()
operator。这不是我的意思。如何更好地表达这个问题。。。我不是问如何过滤(或限制)现有流,而是问如何动态创建(生成)流,而不预先加载所有元素,但流的大小有限(事先未知)
解决方案
我要找的代码是
Iterator it = myCustomIteratorThatGeneratesTheSequence();
StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false);
我刚刚研究了java.nio.file.Files
,list(path)
方法是如何实现的
在Java中有没有合理的简单方法可以做到这一点,而不必自己实现整个流接口
一个简单的.limit()
保证它将终止。但这并不总是足够强大
在
流
工厂方法之后,创建自定义流源而不重新实现流处理管道的最简单方法是对java.util.Spliterators.AbstractSpliterator进行子类化,并将其传递给java.util.Stream.StreamSupport.Stream(供应商Kotlin从InputStream创建JsonNode流的代码
private fun InputStream.toJsonNodeStream(): Stream<JsonNode> {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(this.toJsonNodeIterator(), Spliterator.ORDERED),
false
)
}
private fun InputStream.toJsonNodeIterator(): Iterator<JsonNode> {
val jsonParser = objectMapper.factory.createParser(this)
return object: Iterator<JsonNode> {
override fun hasNext(): Boolean {
var token = jsonParser.nextToken()
while (token != null) {
if (token == JsonToken.START_OBJECT) {
return true
}
token = jsonParser.nextToken()
}
return false
}
override fun next(): JsonNode {
return jsonParser.readValueAsTree()
}
}
}
private fun InputStream.toJsonNodeStream():Stream{
returnstreamsupport.stream(
Spliterators.spliteratorUnknownSize(this.toJsonNodeIterator(),Spliterator.ORDERED),
假的
)
}
private fun InputStream.toJsonNodeIterator():迭代器{
val jsonParser=objectMapper.factory.createParser(this)
返回对象:迭代器{
override fun hasNext():Boolean{
var token=jsonParser.nextToken()
while(令牌!=null){
if(token==JsonToken.START\u对象){
返回真值
}
token=jsonParser.nextToken()
}
返回错误
}
重写fun next():JsonNode{
返回jsonParser.readValueAsTree()
}
}
}
这是一个自定义且有限的流:
package org.tom.stream;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
public class GoldenStreams {
private static final String IDENTITY = "";
public static void main(String[] args) {
Stream<String> stream = java.util.stream.StreamSupport.stream(new Spliterator<String>() {
private static final int LIMIT = 25;
private int integer = Integer.MAX_VALUE;
{
integer = 0;
}
@Override
public int characteristics() {
return Spliterator.DISTINCT;
}
@Override
public long estimateSize() {
return LIMIT-integer;
}
@Override
public boolean tryAdvance(Consumer<? super String> arg0) {
arg0.accept(IDENTITY+integer++);
return integer < 25;
}
@Override
public Spliterator<String> trySplit() {
System.out.println("trySplit");
return null;
}}, false);
List<String> peeks = new ArrayList<String>();
List<String> reds = new ArrayList<String>();
stream.peek(data->{
peeks.add(data);
}).filter(data-> {
return Integer.parseInt(data)%2>0;
}).peek(data ->{
System.out.println("peekDeux:"+data);
}).reduce(IDENTITY,(accumulation,input)->{
reds.add(input);
String concat = accumulation + ( accumulation.isEmpty() ? IDENTITY : ":") + input;
System.out.println("reduce:"+concat);
return concat;
});
System.out.println("Peeks:"+peeks.toString());
System.out.println("Reduction:"+reds.toString());
}
}
package org.tom.stream;
导入java.util.*;
导入java.util.function.*;
导入java.util.stream.*;
公共级黄金流{
私有静态最终字符串标识=”;
公共静态void main(字符串[]args){
Stream-Stream=java.util.Stream.StreamSupport.Stream(新的拆分器(){
专用静态最终整数限值=25;
private int integer=integer.MAX_值;
{
整数=0;
}
@凌驾
公共int特性(){
返回拆分器.DISTINCT;
}
@凌驾
公共长期估计规模(){
返回极限整数;
}
@凌驾
public boolean tryAdvance(ConsumerI认为我不明白。您是否正在寻找类似于此处的takeWhile
方法?您是否看过类似于和friends的方法?openjdk 9
提供了takeWhile()
@JanXMarek一种方法是使用此答案创建一个迭代器
,然后使用此答案将迭代器
转换为一个流
。这样迭代器将只在内存中保存一小堆文件,流将被惰性地计算。不过这是一项大量的工作。我强烈建议首先使用check在执行更复杂的迭代器
之前,先确定拆分器
的逻辑是否更合适,然后再将其封装在拆分器
中。参见示例…