如何延迟连接流?

2024-04-03

我正在尝试实现一个在其实现中使用其自身的另一个实例的流。该流前面有一些常量元素(使用 IntStream.concat),因此只要串联流惰性地创建非常量部分,这应该就可以工作。我认为使用StreamSupport.intStream 重载采用供应商 https://docs.oracle.com/javase/8/docs/api/java/util/stream/StreamSupport.html#intStream-java.util.function.Supplier-int-boolean-与 IntStream.concat (其中“创建一个延迟连接的流” https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#concat-java.util.stream.IntStream-java.util.stream.IntStream-)应该足够懒,只在需要元素时才创建第二个分割器,但即使创建流(不评估它)也会溢出堆栈。如何延迟连接流?


我正在尝试从以下位置移植流式素数筛这个答案 https://stackoverflow.com/a/10733621/3614835进入Java。该筛子使用其自身的另一个实例(ps = postponed_sieve()在 Python 代码中)。如果我破坏最初的四个常量元素(yield 2; yield 3; yield 5; yield 7;)到他们自己的流中,很容易将生成器实现为分割器:

/**
 * based on https://stackoverflow.com/a/10733621/3614835
 */
static class PrimeSpliterator extends Spliterators.AbstractIntSpliterator {
    private static final int CHARACTERISTICS = Spliterator.DISTINCT | Spliterator.IMMUTABLE | Spliterator.NONNULL | Spliterator.ORDERED | Spliterator.SORTED;
    private final Map<Integer, Supplier<IntStream>> sieve = new HashMap<>();
    private final PrimitiveIterator.OfInt postponedSieve = primes().iterator();
    private int p, q, c = 9;
    private Supplier<IntStream> s;
    PrimeSpliterator() {
        super(105097564 /* according to Wolfram Alpha */ - 4 /* in prefix */,
                CHARACTERISTICS);
        //p = next(ps) and next(ps) (that's Pythonic?)
        postponedSieve.nextInt();
        this.p = postponedSieve.nextInt();
        this.q = p*p;
    }

    @Override
    public boolean tryAdvance(IntConsumer action) {
        for (; c > 0 /* overflow */; c += 2) {
            Supplier<IntStream> maybeS = sieve.remove(c);
            if (maybeS != null)
                s = maybeS;
            else if (c < q) {
                action.accept(c);
                return true; //continue
            } else {
                s = () -> IntStream.iterate(q+2*p, x -> x + 2*p);
                p = postponedSieve.nextInt();
                q = p*p;
            }
            int m = s.get().filter(x -> !sieve.containsKey(x)).findFirst().getAsInt();
            sieve.put(m, s);
        }
        return false;
    }
}

我第一次尝试 primes() 方法返回一个 IntStream,它将常量流与新的 PrimeSpliterator 连接起来:

public static IntStream primes() {
    return IntStream.concat(IntStream.of(2, 3, 5, 7),
            StreamSupport.intStream(new PrimeSpliterator()));
}

调用 primes() 会导致 StackOverflowError,因为 primes() 始终实例化 PrimeSpliterator,但 PrimeSpliterator 的字段初始值设定项始终调用 primes()。然而,StreamSupport.intStream 的重载需要一个供应商,这应该允许延迟创建 PrimeSpliterator:

public static IntStream primes() {
    return IntStream.concat(IntStream.of(2, 3, 5, 7),
            StreamSupport.intStream(PrimeSpliterator::new, PrimeSpliterator.CHARACTERISTICS, false));
}

然而,我却得到了一个具有不同回溯的 StackOverflowError (在重复时进行了修剪)。请注意,递归完全发生在对 primes() 的调用中——终端操作 iterator() 永远不会在返回的流上调用。

Exception in thread "main" java.lang.StackOverflowError
    at java.util.stream.StreamSpliterators$DelegatingSpliterator$OfInt.<init>(StreamSpliterators.java:582)
    at java.util.stream.IntPipeline.lazySpliterator(IntPipeline.java:155)
    at java.util.stream.IntPipeline$Head.lazySpliterator(IntPipeline.java:514)
    at java.util.stream.AbstractPipeline.spliterator(AbstractPipeline.java:352)
    at java.util.stream.IntPipeline.spliterator(IntPipeline.java:181)
    at java.util.stream.IntStream.concat(IntStream.java:851)
    at com.jeffreybosboom.projecteuler.util.Primes.primes(Primes.java:22)
    at com.jeffreybosboom.projecteuler.util.Primes$PrimeSpliterator.<init>(Primes.java:32)
    at com.jeffreybosboom.projecteuler.util.Primes$$Lambda$1/834600351.get(Unknown Source)
    at java.util.stream.StreamSpliterators$DelegatingSpliterator.get(StreamSpliterators.java:513)
    at java.util.stream.StreamSpliterators$DelegatingSpliterator.estimateSize(StreamSpliterators.java:536)
    at java.util.stream.Streams$ConcatSpliterator.<init>(Streams.java:713)
    at java.util.stream.Streams$ConcatSpliterator$OfPrimitive.<init>(Streams.java:789)
    at java.util.stream.Streams$ConcatSpliterator$OfPrimitive.<init>(Streams.java:785)
    at java.util.stream.Streams$ConcatSpliterator$OfInt.<init>(Streams.java:819)
    at java.util.stream.IntStream.concat(IntStream.java:851)
    at com.jeffreybosboom.projecteuler.util.Primes.primes(Primes.java:22)
    at com.jeffreybosboom.projecteuler.util.Primes$PrimeSpliterator.<init>(Primes.java:32)
    at com.jeffreybosboom.projecteuler.util.Primes$$Lambda$1/834600351.get(Unknown Source)
    at java.util.stream.StreamSpliterators$DelegatingSpliterator.get(StreamSpliterators.java:513)
    at java.util.stream.StreamSpliterators$DelegatingSpliterator.estimateSize(StreamSpliterators.java:536)
    at java.util.stream.Streams$ConcatSpliterator.<init>(Streams.java:713)
    at java.util.stream.Streams$ConcatSpliterator$OfPrimitive.<init>(Streams.java:789)
    at java.util.stream.Streams$ConcatSpliterator$OfPrimitive.<init>(Streams.java:785)
    at java.util.stream.Streams$ConcatSpliterator$OfInt.<init>(Streams.java:819)
    at java.util.stream.IntStream.concat(IntStream.java:851)
    at com.jeffreybosboom.projecteuler.util.Primes.primes(Primes.java:22)

如何足够懒惰地连接流以允许流在其实现中使用自身的另一个副本?


您显然认为 Streams API 将其惰性保证扩展到了 spliterator 的实例化;这是不正确的。它期望能够在实际消费开始之前随时实例化流的分割器,例如只是为了找出流的特征和报告的大小。消费仅通过调用开始trySplit, tryAdvance, or forEachRemaining.

考虑到这一点,您可以在需要之前初始化推迟的筛选。您无法使用其任何结果,直到else if参与tryAdvance。因此,将代码移至最后可能的时刻,以保证正确性:

@Override
public boolean tryAdvance(IntConsumer action) {
    for (; c > 0 /* overflow */; c += 2) {
        Supplier<IntStream> maybeS = sieve.remove(c);
        if (maybeS != null)
            s = maybeS;
        else {
            if (postponedSieve == null) {
              postponedSieve = primes().iterator();
              postponedSieve.nextInt();
              this.p = postponedSieve.nextInt();
              this.q = p*p;
            }
            if (c < q) {
              action.accept(c);
              return true; //continue

我认为,有了这个改变,即使你第一次尝试primes()应该管用。

如果您想继续使用当前的方法,您可以使用以下习惯用法:

Stream.<Supplier<IntStream>>of(
  ()->IntStream.of(2, 3, 5, 7),
  ()->intStream(new PrimeSpliterator()))
.flatMap(Supplier::get);

你可能会发现这给了你足够多的懒惰。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何延迟连接流? 的相关文章

  • 如何使用 Java 中的 Web 服务(例如 Axis2)发送复杂对象的数组或集合?

    我对 SOAP Web 服务还比较陌生 虽然我完成了一些较小的 Web 服务项目 但我偶然从来不需要返回 或用作参数 复杂 对象的数组或集合 当我尝试这样做时 根据我的 SOAP 绑定风格 我会得到不同的奇怪行为 当我使用RPC 文字 我可
  • Java:迭代 Collection 的最佳方法(此处为 ArrayList)

    今天 当我看到一段我已经使用了数百次的代码时 我很高兴地开始编码 迭代集合 此处为 ArrayList 出于某种原因 我实际上查看了 Eclipse 的自动完成选项 这让我想知道 在什么情况下以下循环比其他循环更好使用 经典的数组索引循环
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • JAVA - Xuggler - 组合 MP3 音频文件和 MP4 电影时播放视频

    使用 JAVA 和 Xuggler 以下代码组合 MP3 音频文件和 MP4 电影文件并输出组合的 mp4 文件 我希望在合并音频和视频文件时应自动播放输出视频文件 String inputVideoFilePath in mp4 Stri
  • Java 文件上传速度非常慢

    我构建了一个小型服务 它从 Android 设备接收图像并将其保存到 Amazon S3 存储桶中 代码非常简单 但是速度非常慢 事情是这样的 public synchronized static Response postCommentP
  • 画透明圆,外面填充

    我有一个地图视图 我想在其上画一个圆圈以聚焦于给定区域 但我希望圆圈倒转 也就是说 圆的内部不是被填充 而是透明的 其他所有部分都被填充 请参阅这张图片了解我的意思 http i imgur com zxIMZ png 上半部分显示了我可以
  • Calendar.getInstance(TimeZone.getTimeZone("UTC")) 不返回 UTC 时间

    我对得到的结果真的很困惑Calendar getInstance TimeZone getTimeZone UTC 方法调用 它返回 IST 时间 这是我使用的代码 Calendar cal Two Calendar getInstance
  • Java 8 流 - 合并共享相同 ID 的对象集合

    我有一系列发票 class Invoice int month BigDecimal amount 我想合并这些发票 这样我每个月都会收到一张发票 金额是本月发票金额的总和 例如 invoice 1 month 1 amount 1000
  • 将 SignedHash 插入 PDF 中以进行外部签名过程 -workingSample

    遵循电子书第 4 3 3 节 PDF 文档的数字签名 https jira nuxeo com secure attachment 49931 digitalsignatures20130304 pdf 我正在尝试创建一个工作示例 其中 客
  • Java 中的“Lambdifying”scala 函数

    使用Java和Apache Spark 已用Scala重写 面对旧的API方法 org apache spark rdd JdbcRDD构造函数 其参数为 AbstractFunction1 abstract class AbstractF
  • 普罗米修斯指标 - 未找到

    我有 Spring Boot 应用程序 并且正在使用 vertx 我想监控服务和 jvm 为此我选择了 Prometheus 这是我的监控配置类 Configuration public class MonitoringConfig Bea
  • 如何在 Java 中测试一个类是否正确实现了 Serialized(不仅仅是 Serialized 的实例)

    我正在实现一个可序列化的类 因此它是一个与 RMI 一起使用的值对象 但我需要测试一下 有没有办法轻松做到这一点 澄清 我正在实现该类 因此在类定义中添加 Serialized 很简单 我需要手动序列化 反序列化它以查看它是否有效 我找到了
  • 欧洲中部时间 14 日 3 月 30 日星期五 00:00:00 至 日/月/年

    我尝试解析格式日期Fri Mar 30 00 00 00 CET 14至 日 月 年 这是我的代码 SimpleDateFormat formatter new SimpleDateFormat dd MM yyyy System out
  • 测试弱引用

    在 Java 中测试弱引用的正确方法是什么 我最初的想法是执行以下操作 public class WeakReferenceTest public class Target private String value public Targe
  • 游戏内的java.awt.Robot?

    我正在尝试使用下面的代码来模拟击键 当我打开记事本时 它工作正常 但当我打开我想使用它的游戏时 它没有执行任何操作 所以按键似乎不起作用 我尝试模拟鼠标移动和点击 这些动作确实有效 有谁知道如何解决这个问题 我发现这个问题 如何在游戏中使用
  • hashcode 的默认实现为以相同方式构造的对象返回不同的值

    我在这里编写一个示例代码 public class Test private int i private int j public Test TODO Auto generated constructor stub public Test
  • 如何从 Maven 存储库引用本机 DLL?

    如果 JAR 附带 Maven 存储库中的本机 DLL 我需要在 pom xml 中放入什么才能将该 DLL 放入打包中 更具体地举个例子Jacob http search maven org artifactdetails 7Cnet s
  • 在 RESTful Web 服务中实现注销

    我正在开发一个需要注销服务的移动应用程序 登录服务是通过数据库验证来完成的 现在我陷入了注销状态 退一步 您没有提供有关如何在应用程序中执行身份验证的详细信息 并且很难猜测您在做什么 但是 需要注意的是 在 REST 应用程序中 不能有会话
  • GUI Java 程序 - 绘图程序

    我一直试图找出我的代码有什么问题 这个想法是创建一个小的 Paint 程序并具有红色 绿色 蓝色和透明按钮 我拥有我能想到的让它工作的一切 但无法弄清楚代码有什么问题 该程序打开 然后立即关闭 import java awt import
  • 如何修复:“无法解析类型 java.lang.CharSequence。它是从所需的 .class 文件间接引用的”消息? [复制]

    这个问题在这里已经有答案了 我正在尝试使用这个字符串 amountStr amountStr replace replace replace 但我收到一条错误消息 我知道我收到的错误消息是因为我刚刚发布的字符串已过时 所以我想知道该字符串的

随机推荐

  • 2 个 IndexedSlices 不支持高效 allreduce

    我正在尝试在多个 GPU 上运行子类 Keras 模型 代码按预期运行 但是在代码执行过程中出现以下 警告 2 个 IndexedSlices 不支持高效 allreduce 这是什么意思 我遵循 Tensorflow 2 0 Beta 指
  • 为什么 CSS 光标属性不适用于样式化滚动条?

    我设计了一个滚动条 but 光标指针不工作 即使我把 important webkit scrollbar width 0 3vw height 20px padding 2px cursor pointer important Handl
  • 两个 WPF 应用程序之间的通信

    我有两个 WPF 应用程序 我需要这两个应用程序能够相互通信 我只需要这些应用程序相互发送一些通知 仅此而已 我已经找到了两种技术 一种是使用WCF 另一种是使用DDE 但对我来说 这些对于我的要求来说似乎太复杂了 请建议最简单的方法是什么
  • Internet Explorer中跨域POST请求ajax

    我正在使用 jQuery 1 7 2 并且想向另一个域发出 POST 请求 它必须是 POST 请求 但这确实无法在 Internet Explorer 中工作 我在IE9上试过 它适用于所有其他浏览器 我有这个脚本
  • Java中将short转换为byte[]

    我怎样才能转换short 2 个字节 到 Java 中的字节数组 例如 short x 233 byte ret new byte 2 应该是这样的 但不确定 0xFF lt lt 8 x gt gt 0 EDIT 您还可以使用 java
  • 查找我的数据库的 DSN?

    我有一个 SQL 数据库 想要使用 VBA 连接到它以支持一些旧功能 我正在使用 ADODB 连接 需要知道我的数据库 DSN 是什么 我怎样才能找到这个 我正在使用 SQL Server 2008 谢谢 D A DSN 数据源名称 htt
  • Laravel 从嵌套关系中取出一个数组

    我只需要得到roomnumber从以下查询返回的数组 roomnumbers Room with floorroomcount gt function query query gt with roomnumber gt get gt whe
  • java队列中Queue.Poll()返回null但Queue.size()>0

    My code while Memo qRcv size gt 0 MessageReceived msg Memo qRcv poll 然后我得到了 2014 03 01 11 09 36 DEBUG Thread 16 threadQu
  • 如何将时间序列数据中的y%m%d%H格式转换为“%Y%m%d %H:%M:%S”

    我如何转换y m d H格式化为 Y m d H M S 我的日期从 1970 年到 2010 年 部分来自评论 如果您可以相应地修改问题 那就太好了 似乎这不是格式化的情况 y vs Y或空格 分隔符 但是strptime POSIX t
  • C谜题:用有偏差的硬币制造公平的硬币

    如何确定函数在以下情况下返回 0 或 1 的概率 Let the function A返回 0 与 概率 40 和 1 有概率 60 生成一个function B和 概率 50 50 仅使用function A only 我想到了以下几点
  • Java读取文件,如果不存在则创建它

    这是我的代码 public String path public String fileName public static void readData throws IOException try path myPath fileName
  • 具有固定大小的 Blackberry VerticalFieldManager:滚动问题

    我试图拥有一个带有修复标题 带有某些字段的管理器 和可滚动内容 自定义字段列表 的全屏用户界面 这个想法是模拟一种可滚动列表 为此 我制作了一个接受 maxHeight 屏幕高度 标题高度 的自定义 VerticalFieldManager
  • NSPopover 内的 NSTableview 看起来与独立的不同

    我创建了一个ListView类 这是一个非常简单的Tableview 如果我用 IB 实例化它 一切看起来都很好 如果我以编程方式实例化它也是一样 如果我在一个内部以编程方式实例化它NSPopover 我的桌子的每一行都有浅灰色背景 这是从
  • 为什么 form.submit() 不起作用?

    我在页面中有以下片段 我一生都无法弄清楚为什么单击button1元素时表单没有提交 我在 IE 中收到错误消息 指出该对象不支持此属性或方法 我将 document poform 放入警报中 它会警报表单对象 我感觉我可能错过了一些非常明显
  • 某些设备上的 Android 中出现“没有这样的表”问题

    我在 Android 应用程序中使用外部数据库 它在所有模拟器和三星真实设备上运行良好 但是当我检查宏碁智能手机时 我的应用程序崩溃并出现以下异常 android database sqlite SQLiteException no suc
  • 可变结构与类?

    我不确定是否使用可变结构或可变类 我的程序存储一个包含很多对象的数组 我注意到使用类会使所需的内存量增加一倍 但是 我希望对象是可变的 并且有人告诉我使用可变结构是邪恶的 这就是我的类型 struct or class Block publ
  • 将 Flash (AS3) 数据保存为 XML

    我在互联网上 包括 Stack Overflow 花了好几个小时 试图找到一个可靠的 可行的示例 将 Flash 中的信息保存到 XML 文件中 我想获取两种不同类型对象的位置并将每个对象的列表导出到 XML 我们将调用这些对象ball a
  • PHP 5.3.3 中的 ini_set("memory_limit") 根本不起作用

    我之前有过这样的工作 echo ini get memory limit n ini set memory limit 256M echo ini get memory limit n 这将输入 32M 256M 在通过命令行执行的 php
  • 如何在 C# HttpClient 中循环调用分页 URL 以从 JSON 结果下载所有页面

    我的第一个问题 所以请友善 我正在使用C HttpClient调用作业 API 端点 这是端点 Jobs API Endpoint 不需要密钥 点击即可 http service dice com api rest jobsearch v1
  • 如何延迟连接流?

    我正在尝试实现一个在其实现中使用其自身的另一个实例的流 该流前面有一些常量元素 使用 IntStream concat 因此只要串联流惰性地创建非常量部分 这应该就可以工作 我认为使用StreamSupport intStream 重载采用