Java 8引入了一个类似于Scala的Stream的Stream类,它是一个强大的惰性构造,使用它可以非常简洁地执行以下操作:
def from(n: Int): Stream[Int] = n #:: from(n+1)
def sieve(s: Stream[Int]): Stream[Int] = {
s.head #:: sieve(s.tail filter (_ % s.head != 0))
}
val primes = sieve(from(2))
primes takeWhile(_ < 1000) print // prints all primes less than 1000
我想知道是否可以在Java 8中执行此操作,所以我写了如下代码:
IntStream from(int n) {
return IntStream.iterate(n, m -> m + 1);
}
IntStream sieve(IntStream s) {
int head = s.findFirst().getAsInt();
return IntStream.concat(IntStream.of(head), sieve(s.skip(1).filter(n -> n % head != 0)));
}
IntStream primes = sieve(from(2));
相当简单,但它产生的java.lang.IllegalStateException: stream has already been operated upon or closed
原因是findFirst()
和skip()
都是终端操作,Stream
只能在该终端上执行一次。
我真的不需要用完两次流,因为我需要的只是流中的第一个数字,其余作为另一个流,即Scala
Stream.head
和的等效项Stream.tail
。Java 8 Stream
中是否可以使用一种方法来实现此目的?
谢谢。
即使您没有无法分割的问题IntStream
,您的代码也不起作用,因为您是sieve
递归地而不是惰性地调用方法。因此,在查询结果流中的第一个值之前,您必须进行无穷递归。
可以IntStream s
将a分为头和尾IntStream
(尚未消耗):
PrimitiveIterator.OfInt it = s.iterator();
int head = it.nextInt();
IntStream tail = IntStream.generate(it::next).filter(i -> i % head != 0);
在这个地方,您需要sieve
懒惰地调用尾部的构造。Stream
不提供;concat
期望将现有流实例作为参数,并且您不能构造sieve
带有lambda表达式的延迟调用的流,因为惰性创建仅在可变状态下才起作用,而lambda表达式不支持这种状态。如果您没有隐藏可变状态的库实现,则必须使用可变对象。但是,一旦您接受了可变状态的要求,该解决方案甚至比第一种方法更容易:
IntStream primes = from(2).filter(i -> p.test(i)).peek(i -> p = p.and(v -> v % i != 0));
IntPredicate p = x -> true;
IntStream from(int n)
{
return IntStream.iterate(n, m -> m + 1);
}
这将递归地创建一个过滤器,但是最后无论创建一个IntPredicate
s的树还是一个s的树都没有关系IntStream
(就像您的IntStream.concat
方法可行一样)。如果您不喜欢过滤器的可变实例字段,则可以将其隐藏在内部类中(而不是在lambda表达式中)。
我是使用Java8流API的新手,但我希望使用它来解决以下问题。假设我有一个名为的POJO,它包含、和属性,这些属性可以表示以下内容的每一行记录: 看起来如下: 上述四条记录需要合并为两条按名称分组的记录,其中: 属性求和 属性求和 组合记录包括属性,该属性是和的累加和相乘的结果。 因此,上述结果将是: 一个名为的不同POJO将表示组合记录的每一行记录: 有哪些好的方法/解决方案可以将输入的列表转
我有一节这样的课 如果我有一个此类对象的列表,如下所示
问题内容: 假设您有一个txt文件,同时查看文件的前10行和后10行的命令是什么? 即,如果文件长200行,则可以一次性查看1-10行和190-200行。 问题答案: 您可以简单地: 如果由于某种原因需要使用管道,则如下所示: 注意:如果file.txt中的行数小于默认的head行+默认的tail行,则将打印重复的行。
问题内容: 当我们需要调用Ajax请求时,我们要做的是: 我已经知道,使用,我们可以提出跨源请求 , 并且添加了ORIGIN标头。 题: 何时 添加此标头? 当浏览器(支持CORS)执行请求时是否添加?(跨域还是非跨域?) 还是在浏览器“看到”请求目标来源与当前来源不同时自动添加? 我的意思是:He **是什么意思? 跨域HTTP请求具有一个Origin头。该头为服务器提供请求的来源。此标头受浏览
我正在尝试查找有关RabbitMQ使用的标准AMQP标头和AMQP协议保留的文档。我已经查看了AMQP文档和RabbitMQ的网站,但没有运气。是否有包含此信息的资源?谢谢。
主要内容:1 HTTP Request Header请求头,2 HTTP Response Header 响应头本文列出了日常开发中常见的请求头和响应头,以供大家参考。 1 HTTP Request Header请求头 Header 说明 示例 Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html Accept-Charset 浏览器可以接受的字符编码集。 Accept-Charset: iso-8859-5 Accept-Encoding