我正在写一个计算斐波那契数的代码。使用这段代码,我可以生成斐波那契数列的前n个数。
Stream.generate(new Supplier<Long>() {
private long n1 = 1;
private long n2 = 2;
@Override
public Long get() {
long fibonacci = n1;
long n3 = n2 + n1;
n1 = n2;
n2 = n3;
return fibonacci;
}
}).limit(50).forEach(System.out::println);
方法limit
返回Stream
,它保存传递给此方法的元素的数量。我想在斐波那契数达到一定值后停止生成Stream
。
我的意思是,如果我想列出所有小于1000的斐波纳契数,我就不能使用limit
,因为我不知道可能有多少斐波纳契数。
有没有办法使用lambda表达式来做到这一点?
发布于 2014-02-09 03:29:21
如果你不介意使用迭代器,你可以把它写成:
static LongUnaryOperator factorial = x -> x == 0 ? 1
: x * factorial.applyAsLong(x - 1);
public static void main(String[] args) {
LongStream ls = LongStream.iterate(0, i -> i + 1).map(factorial);
OfLong it = ls.iterator();
long next = 0;
while ((next = it.nextLong()) <= 1000) System.out.println(next);
}
发布于 2014-02-12 03:38:35
我能找到的使用Stream
内置功能的最佳解决方案是:
LongStream.generate(new LongSupplier() {
private long n1 = 1, n2 = 2;
public long getAsLong() {
long fibonacci = n1;
long n3 = n2 + n1;
n1 = n2;
n2 = n3;
return fibonacci;
}
}).peek(System.out::println).filter(x->x>1000).findFirst();
不过,它的缺点是处理第一个项目是>=1000
。这可以通过使语句具有条件来防止,例如
.peek(x->{if(x<=1000) System.out.println(x);}).filter(x->x>1000).findFirst();
但我不喜欢对同一条件(大于或不大于1000)进行两次评估。但是,对于需要基于结果值的限制的实际任务,这两种解决方案中的一种可能足够实用。
我认为,很明显,整个结构并不是能够并行的…
发布于 2014-02-09 03:03:35
是的,有一种lambda方法,但不幸的是,我不认为它是在当前的Java8API中实现的。很抱歉给您介绍一种不同的语言,但我认为您需要的是类似于
takeWhile(p: (A) ⇒ Boolean): Stream[A]
来自Scala Stream API。
因为这不是在Java API中实现的,所以您必须自己完成。这个怎么样:
public static List<T> takeWhile(Iterable<T> elements, Predicate<T> predicate) {
Iterator<T> iter = elements.iterator();
List<T> result = new LinkedList<T>();
while(iter.hasNext()) {
T next = iter.next();
if (predicate.apply(next)) {
result.add(next);
} else {
return result; // Found first one not matching: abort
}
}
return result; // Found end of the elements
}
然后你可以像这样使用它
List<Long> fibNumbersUnderThousand = takeWhile(allFibNumStream, l -> l < 1000);
(假设Stream
是Iterable
的一个实例-如果不是,您可能需要调用.iterator()
方法并将其包装起来)
https://stackoverflow.com/questions/21650155
复制相似问题