当前位置: 首页 > 知识库问答 >
问题:

Java流API惰性评估内部构件

储法
2023-03-14

我正在写一篇关于Java流API的文章。我已经阅读了Stream的整个软件包文档,并在这里查看了类似的问题。

如果我说:“直到终端操作被命中,才会评估流上的中间操作,这将实际执行它们,”我是否正确?我在StackOverflow上看到了混合答案,而且每个中间操作都返回一个Stream,所以我想知道它是否只是返回自己,然后只是跟踪要执行的中间操作。这就是“懒惰评估/执行”的意思吗?

下面的javadoc给了我混合的信号。。也许我只是个傻瓜

中间操作返回一个新流。他们总是懒惰;执行中间操作(如filter())实际上并不执行任何过滤,而是创建一个新的流,在遍历时,该流包含与给定谓词匹配的初始流的元素。在执行管道的终端操作之前,不会开始遍历管道源。

非常感谢您抽出时间!如果我错过了什么,我很抱歉;(我已经在这上面呆了很长时间了!

附注:流和惰性评估非常相似,但是“每个中间操作都会创建一个新流,存储提供的操作/函数并返回新流。”所以基本上,我的问题是,新流是指与给定的流相同吗?

共有2个答案

呼延震博
2023-03-14

如果我说:“直到终端操作被命中,才对流上的中间操作进行评估,而终端操作将实际执行它们”,我是否正确?

我想知道它是否只是自己返回,然后跟踪要执行的中间操作。

它返回一个新的Stream对象,该对象是根据之前的Stream对象定义的。

岳奇逸
2023-03-14

所以我想知道它是不是自己回来了

中间操作不返回给定的流。正如JavaDoc所说,它们返回一个新流,即一个新对象。

如果它是一个新对象,它如何知道以前在流上完成的操作?

...你可能会问。

对象可以引用其他对象,对吗?即使您返回一个执行“映射”的新流,它仍然可以引用“旧流”(即上游)。非常简单的示例:

class StreamThatDoesMapping<U, T> implements Stream<T> {
    private Stream<U> upstream;
    private Function<? super U, ? extends T> mappingFunction;

    public StreamThatDoesMapping(Stream<U> upstream, Function<? super U, ? extends T> mappingFunction) {
        this.upstream = upstream;
        this.mappingFunction = mappingFunction;
    }

    // implementation details...
}

显然,在实现映射时,如果您随后将上游()传递给进行映射的流,则新流将“了解”您之前执行的操作!这是您实现映射的方式,同样非常简单:

public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
    return new StreamThatDoesMapping<>(this, mapper);
}

当您执行终端操作时,您正在“最下游”流对象上执行,该对象将从其上游获取元素,而该上游将从其上游获取元素,依此类推。有点像链表,不是吗?

请注意,这只是下游了解上游的一种方式。可能还有其他的,但这就是ReferencePipeline实现所使用的。这是JDK中大多数stream()方法返回的内容。我强烈建议查看他们的源代码。

 类似资料:
  • 问题内容: 我知道Java在这种情况下具有智能/惰性评估: 但是关于: 即使返回true 也被调用? 问题答案: 在Java(和其他类似C的语言)中,这称为 短路评估 。* 是的,在第二个示例中总是被调用。也就是说,除非编译器/ JVM可以确定它没有可观察到的副作用,否则在这种情况下它可以选择进行优化,但是无论如何您都不会注意到它们之间的差异。 两者截然不同; 前者本质上是一种优化技术,而第二种则

  • 问题内容: 什么是Python中的惰性评估? 一个网站说: 在Python 3.x中,该函数返回一个特殊的范围对象,该对象按需计算列表元素(延迟或延迟评估): 这是什么意思? 问题答案: 由(或在Python2.x中)返回的对象被称为惰性迭代。 生成器没有将整个范围存储在内存中,而是存储的定义并仅在需要时才计算下一个值(又称惰性求值)。 本质上,生成器允许您返回类似于结构的列表,但是这里有一些区别

  • 我明白,如果我有一个来自列表(例如过滤器)的惰性流,在我开始对流进行迭代之前,对条件的检查不会开始。 编辑3(编辑示例以使其清晰)-例如: 如果在最后一行中,它将花费几次时间来找到第一个元素或不找到。

  • 问题内容: 我最近读到了Python 3的一个好处是它很懒。那就更好了 而不是 我很好奇的是如何使用这种懒惰。如果生成映射对象,例如,如何访问生成的操作/列表中的特定元素。在我所见过的几乎所有文档中,他们都会做类似或的事情(据我所知),它放弃了惰性概念,因为它隐式将地图转换为列表。 我想我正在寻找的是能够以与我可以懒惰地懒惰地生成地图对象类似的方式使用地图对象的能力,并且可以在没有巨大计算量的情况

  • 问题内容: 我正在尝试在Python3中使用。这是我正在使用的一些代码: 但是,由于在Python3中返回了迭代器,因此该代码在Python3中不起作用(但在Python2中可以正常工作,因为该版本的always返回a ) 我当前的解决方案是在迭代器上添加一个函数调用以强制求值。但这似乎很奇怪(我不在乎返回值,为什么要将迭代器转换为列表?) 有更好的解决方案吗? 问题答案: 当您对返回的值不感兴趣

  • 问题内容: 我正在类之间进行一些Java性能比较,并想知道是否存在某种Java Performance Framework可以简化编写性能测量代码的过程? 即,我现在正在尝试测量与使用AtomicInteger作为我的“同步器”相比,使用PseudoRandomUsingSynch.nextInt()中的“同步”方法具有什么效果。 因此,我尝试使用3个线程访问10000次同步方法循环来测量生成随机