Java IntStream 在尝试解决代码战问题时出现问题(Prime Streaming PG-13)

问题描述 投票:0回答:1

我在 3 月份报名参加了 codewars,我已经完成了一些挑战。我在以下方面遇到困难。名称是 Prime Streaming (PG-13),并在下方突出显示。 创建无穷无尽的素数流——有点像 IntStream.of(2, 3, 5, 7, 11, 13, 17),但无限。该流必须能够在几秒钟内产生一百万个素数。

这是我试图解决问题的代码。

import java.util.stream.IntStream;
     import java.util.ArrayList;
     import java.util.Arrays;
     public class Primes {
     private static ArrayList<Integer> primes = new ArrayList<Integer>();
     public static IntStream stream() {
      return IntStream.iterate(2,i->i+1).filter(x->isPrime(x)).limit(1000000); 
     }
     private static boolean isPrime(int n) {
      if(n<2) return false;
      for (int i = 0; i < primes.size();i++){
       int x = primes . get( i );
       if ( n % x ==0 ) return false;
      }
      primes.add(n);
      return true;
     }
     }

这些是代码必须通过才能完成挑战的测试。

import org.junit.Test;
   import static org.junit.Assert.assertArrayEquals;
   public class PrimesTest {
    @Test
    public void test_0_10() {
     test(0, 10, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
    }
    @Test
    public void test_10_10() {
     test(10, 10, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71);
    }
    @Test
    public void test_100_10() {
     test(100, 10, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601);
    }
    @Test
    public void test_1000_10() {
     test(1000, 10, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017); 
    }
    private void test(int skip, int limit, int... expect) {
     int[] found = Primes.stream().skip(skip).limit(limit).toArray();
     assertArrayEquals(expect, found);
    }
    }

我的问题是这样的。该代码将通过第一个测试,但不会通过其他测试。我注意到产生的数字是素数,但它在系列中更靠后。显然,每次调用 Primes.stream() 时,它不是从头开始并创建一个新的,而是从上次测试中的素数继续。对于每个进一步的测试,使用第一组素数,它会跳过额外的 10 并调用一个数字。调用的第一个测试是 test_0_10,它正确返回 29。调用的第二个测试是 test_1000_10,它返回 8039 而不是 7927。调用的第三个测试是 test_10_10,它调用 8221 而不是 31。我知道流被延迟评估并怀疑这是问题所在。有人可以帮忙吗?

有关我尝试的内容和结果,请参阅上面的描述

java java-stream primes lazy-evaluation intstream
1个回答
0
投票

您可能必须为每次调用流创建

ArrayList
以防止其先前状态干扰新结果。像下面这样的东西应该可以解决你的问题:

  private static ArrayList<Integer> primes;
  public static IntStream stream() {
    primes = new ArrayList<Integer>();
    return IntStream.iterate(2,i->i+1).filter(x->isPrime(x)).limit(1000000);
  }
© www.soinside.com 2019 - 2024. All rights reserved.