Java 从列表生成延迟流

Java 从列表生成延迟流,java,Java,正如标题中所指出的,我想从列表生成流,但是列表需要很大的性能成本,并且流可能不会被真正使用 我需要这样的东西: Stream<T> stream = Stream.fromList(() -> calculateList(...)) .filter(...) .map(...) // TODO ; //#region some case why I want delayed stream instead of other way. if (c

正如标题中所指出的,我想从列表生成流,但是列表需要很大的性能成本,并且流可能不会被真正使用

我需要这样的东西:

Stream<T> stream = Stream.fromList(() -> calculateList(...))
    .filter(...)
    .map(...)
    // TODO
    ;

//#region some case why I want delayed stream instead of other way.

if (condition$1) {
    // that is why I don't want to re-order those code.
    stream.forEach(...);
    return;
}

var something$1 = ...; // that should only execute after the condition$1 not passed.

if (condition$2) {
    // that is why I don't want to use `Supplier<Stream<T>>`.
    stream = stream.concat(Stream.fromList(() -> calculateOthList(...)));
}

var something$2 = ...;

if (condition$3) {
    // that is why I dont want to use `Stream<Supplier<Stream<T>>>` (and what's more, it not easy to read).
    stream = stream.filter(...).peek(...);
}

... // as you see, the most important thing of those code is to deal the stream, it's data-driven.
//#endregion

// TODO may be return if some condition not passed.
// TODO and even worse, some exception may be throw.

stream.forEach(...); // TODO really use the stream.


Stream<T> lazyStream = Stream.<Supplier<List<T>>>of(() -> calculateList())
            .map(Supplier::get)
            .flatMap(List::stream);
Stream=Stream.fromList(()->calculateList(…)
.filter(…)
.map(…)
//待办事项
;
//#在某些情况下,我希望延迟流而不是其他方式。
如果(条件$1){
//这就是为什么我不想重新排序那些代码。
forEach(…);
回来
}
变量$1=…;/仅应在条件$1未通过后执行。
如果(条件$2){
//这就是为什么我不想使用'Supplier'。
stream=stream.concat(stream.fromList(()->calculateOthList(…));
}
var$2=。。。;
如果(条件$3){
//这就是为什么我不想使用“Stream”(而且,它不容易阅读)。
stream=stream.filter(…).peek(…);
}
... // 如您所见,这些代码中最重要的是处理流,它是数据驱动的。
//#端区
//如果某些条件未通过,TODO可能返回。
//TODO,甚至更糟糕的是,可能会抛出一些异常。
stream.forEach(…);//TODO真的使用了这个流。

有什么内置的方法可以做到这一点吗?或者可能有什么方法可以优雅地实现?

最简单的方法可能是用
供应商替换

Supplier<Stream<T>> stream = () -> Stream.fromList(() -> calculateList(...));
supplierstream=()->stream.fromList(()->calculateList(…);
但如果不能做到这一点,可以实现如下惰性流:

Stream<T> stream = Stream.fromList(() -> calculateList(...))
    .filter(...)
    .map(...)
    // TODO
    ;

//#region some case why I want delayed stream instead of other way.

if (condition$1) {
    // that is why I don't want to re-order those code.
    stream.forEach(...);
    return;
}

var something$1 = ...; // that should only execute after the condition$1 not passed.

if (condition$2) {
    // that is why I don't want to use `Supplier<Stream<T>>`.
    stream = stream.concat(Stream.fromList(() -> calculateOthList(...)));
}

var something$2 = ...;

if (condition$3) {
    // that is why I dont want to use `Stream<Supplier<Stream<T>>>` (and what's more, it not easy to read).
    stream = stream.filter(...).peek(...);
}

... // as you see, the most important thing of those code is to deal the stream, it's data-driven.
//#endregion

// TODO may be return if some condition not passed.
// TODO and even worse, some exception may be throw.

stream.forEach(...); // TODO really use the stream.


Stream<T> lazyStream = Stream.<Supplier<List<T>>>of(() -> calculateList())
            .map(Supplier::get)
            .flatMap(List::stream);
Stream lazyStream=Stream.of(()->calculateList())
.map(供应商::获取)
.flatMap(列表::流);

在这种情况下,您确实需要提供一个供应商。当您需要时,
供应商将评估列表填充方法。有两种方法可以实现这一点:

supplierstreamsupplier=()->calculateList(…).stream();
//其他代码
//然后使用它
streamSupplier.get().forEach(…);
或者你真的想要一条流,所以可以这样做:

Stream<T> stream = Stream.fromList(() -> calculateList(...))
    .filter(...)
    .map(...)
    // TODO
    ;

//#region some case why I want delayed stream instead of other way.

if (condition$1) {
    // that is why I don't want to re-order those code.
    stream.forEach(...);
    return;
}

var something$1 = ...; // that should only execute after the condition$1 not passed.

if (condition$2) {
    // that is why I don't want to use `Supplier<Stream<T>>`.
    stream = stream.concat(Stream.fromList(() -> calculateOthList(...)));
}

var something$2 = ...;

if (condition$3) {
    // that is why I dont want to use `Stream<Supplier<Stream<T>>>` (and what's more, it not easy to read).
    stream = stream.filter(...).peek(...);
}

... // as you see, the most important thing of those code is to deal the stream, it's data-driven.
//#endregion

// TODO may be return if some condition not passed.
// TODO and even worse, some exception may be throw.

stream.forEach(...); // TODO really use the stream.


Stream<T> lazyStream = Stream.<Supplier<List<T>>>of(() -> calculateList())
            .map(Supplier::get)
            .flatMap(List::stream);
Stream calculateList().Stream());
//其他代码
//然后通过解包提供的流来使用它
//然后,我就知道了
StreamOfficers.map(供应商::获取)
.flatMap(函数.identity())
.forEach(…);
这样做的副作用是允许您将多个流放入混合


不过,更大的问题是,为什么不重新组织代码,以便在第一次需要时创建流?

您可以这样做

        List<Integer> list = List.of(1,2,3,4,5,6);
        Function<List<Integer>,Stream<Integer>> fnc = a->a.stream().filter(b->b%2 == 0).map(b->b*20);


        fnc.apply(list).forEach(System.out::println);

您可以从
供应商
创建一个
SPI读写器
,并获得一个流,这会使流创建变得很慢。例如:

 Supplier<Spliterator<Integer>> supplier = () -> calculateList(...).spliterator();
 Stream<Integer> stream = StreamSupport.stream(supplier, Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED, false);
Supplier=()->calculateList(…).spliterator();
Stream Stream=StreamSupport.Stream(供应商、拆分器.ORDERED |拆分器.SIZED |拆分器.SUBSIZED,false);

重新排序您的代码,以便在创建流和使用流之间不会有太大的间隔。
calculateList()
有什么作用?@Michael谢谢,大多数时候我都会重新排序,但这并不总是一个好主意。例如,可能我会根据不同的条件以不同的方式使用流,我会编辑问题并附加一些案例,请稍等片刻,或多或少,但没有
stream.fromList
。他编的。它应该是
()->calculateList(…).stream()
谢谢,在我现在实际处理的情况下,这是最好的方法。但可能延迟的流是有用的,我编辑了我的问题并附加了一些案例。好吧,我再看一遍,发现第二种方法也可以解决我的问题,我误认为它导出了一个流类型的
流。
,但实际上它只是一个中间变量,最后的导出是
Stream
@zhengxiaoyaoyo0716如果答案对你有效,你能接受吗。