注意Java 8的[Primitive] Stream.iterate()中的递归
生活随笔
收集整理的這篇文章主要介紹了
注意Java 8的[Primitive] Stream.iterate()中的递归
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Tagir Valeev關于Stack Overflow的一個有趣問題最近引起了我的注意。 為了簡短起見(請閱讀問題的詳細信息),而以下代碼則有效:
public static Stream<Long> longs() {return Stream.iterate(1L, i ->1L + longs().skip(i - 1L).findFirst().get()); }longs().limit(5).forEach(System.out::println);印刷
1 2 3 4 5以下類似代碼將不起作用:
public static LongStream longs() {return LongStream.iterate(1L, i ->1L + longs().skip(i - 1L).findFirst().getAsLong()); }導致StackOverflowError 。
當然,這種遞歸迭代不是最佳的。 它不是Java 8之前的版本,當然也沒有新的API。 但是有人可能認為它至少應該起作用,對嗎? 之所以不起作用,是因為Java 8中的兩個iterate()方法之間的細微實現差異。雖然引用類型流的Iterator首先返回seed ,然后才通過將迭代函數應用于前一個繼續進行迭代。值:
final Iterator<T> iterator = new Iterator<T>() {@SuppressWarnings("unchecked")T t = (T) Streams.NONE;@Overridepublic boolean hasNext() {return true;}@Overridepublic T next() {return t = (t == Streams.NONE) ? seed : f.apply(t);} };LongStream.iterate()版本(和其他原始流)不是這種情況:
final PrimitiveIterator.OfLong iterator = new PrimitiveIterator.OfLong() {long t = seed;@Overridepublic boolean hasNext() {return true;}@Overridepublic long nextLong() {long v = t;t = f.applyAsLong(t);return v;} };迭代功能已預先預取一個值。 這通常不是問題,但可能導致
作為一種解決方法,最好避免在原始類型流中使用此方法簡單地進行遞歸。 幸運的是,JDK 9中的修復已在進行中(作為功能增強的副作用): https : //bugs.openjdk.java.net/browse/JDK-8072727
翻譯自: https://www.javacodegeeks.com/2016/03/watch-recursion-java-8s-primitivestream-iterate.html
總結
以上是生活随笔為你收集整理的注意Java 8的[Primitive] Stream.iterate()中的递归的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 账户设置没有订阅(账户设置没有订阅选项)
- 下一篇: linux压缩解压缩常用命令(linux