You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java IntStream实现无限素数流的Codewars问题排查

解决Codewars Prime Streaming题目中多次调用stream()状态残留的问题

你遇到的核心问题是静态ArrayList的全局状态残留——第一次调用stream()时生成的素数会被保留在静态列表中,后续调用stream()时,isPrime()方法会基于这个已填充的列表判断,导致流不再从2开始生成新的素数,而是跳过已存在的素数,直接从上次结束的位置继续,最终测试结果偏移。

比如第一次测试后,静态列表已经存储了大量素数,第二次调用stream()时,迭代到2、3等小素数时,要么被isPrime()直接判定为非素数(如果你的逻辑是仅新增未出现的素数),要么重复添加(导致异常或冗余),最终流的输出序列完全偏离预期。

解决方案

1. 用实例化的素数生成器替代静态变量

把素数列表和生成逻辑封装在一个内部类中,每次调用stream()时创建新的生成器实例,确保每个流拥有独立的素数状态,互不干扰。

示例代码:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class PrimeStream {

    public static IntStream stream() {
        // 每次调用stream()都创建新的生成器,状态独立
        PrimeGenerator generator = new PrimeGenerator();
        return Stream.generate(generator::nextPrime)
                .mapToInt(Integer::intValue);
    }

    private static class PrimeGenerator {
        private final List<Integer> primes = new ArrayList<>();
        private int current = 2;

        public int nextPrime() {
            // 单独处理第一个素数2,之后只迭代奇数提升效率
            if (current == 2) {
                primes.add(2);
                current = 3;
                return 2;
            }
            while (true) {
                if (isPrime(current)) {
                    primes.add(current);
                    int result = current;
                    current += 2;
                    return result;
                }
                current += 2;
            }
        }

        private boolean isPrime(int n) {
            for (int p : primes) {
                // 用long避免p*p溢出
                if ((long) p * p > n) {
                    break;
                }
                if (n % p == 0) {
                    return false;
                }
            }
            return true;
        }
    }
}

2. 优化性能满足百万素数要求

上面的实现通过跳过偶数(除了2)减少了一半的判断次数,同时用(long)p*p避免整数溢出,确保判断逻辑正确。对于百万素数的生成需求,试除法在优化后可以达到题目要求的几秒内完成的性能。

关键说明

  • 静态变量的全局共享性是问题根源,改用实例变量后,每个流的生成过程完全独立,不会受之前调用的影响。
  • 用Stream.generate结合有状态的生成器,替代无状态的IntStream.iterate+filter,可以更好地控制素数生成的状态流转。

内容的提问来源于stack exchange,提问作者Hector Williams

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:33:14