我很努力地找到一種方法,以根據謂詞在流的開始處跳過某些元素。Scala的等效下降時間
事情是這樣的:
dropWhile(n -> n < 3, Stream.of(0, 1, 2, 3, 0, 1, 2, 3, 4))
.forEach(System.out::println);
3
0
1
2
3
4
也就是說斯卡拉dropWhile
的等價物。
我很努力地找到一種方法,以根據謂詞在流的開始處跳過某些元素。Scala的等效下降時間
事情是這樣的:
dropWhile(n -> n < 3, Stream.of(0, 1, 2, 3, 0, 1, 2, 3, 4))
.forEach(System.out::println);
3
0
1
2
3
4
也就是說斯卡拉dropWhile
的等價物。
這種操作不是Stream
的預期用例,因爲它包含元素之間的依賴關係。
class MutableBoolean { boolean b; }
MutableBoolean inTail = new MutableBoolean();
IntStream.of(0, 1, 2, 3, 0, 1, 2, 3, 4)
.filter(i -> inTail.b || i >= 3 && (inTail.b = true))
.forEach(System.out::println);
注意,病情比你的例子被逆轉:所以你就來介紹你的謂詞全狀態變量的解決方案可能不會顯得高貴典雅。
當然,你可以隱藏在方法的骯髒細節:
public static void main(String... arg) {
dropWhile(n -> n < 3, Stream.of(0, 1, 2, 3, 0, 1, 2, 3, 4))
.forEach(System.out::println);
}
static <T> Stream<T> dropWhile(Predicate<T> p, Stream<T> s) {
class MutableBoolean { boolean b; }
MutableBoolean inTail = new MutableBoolean();
return s.filter(i -> inTail.b || !p.test(i) && (inTail.b = true));
}
更復雜,但更清潔,可能更有效的辦法是深入到金屬,即Spliterator
接口:
static <T> Stream<T> dropWhile(Predicate<T> p, Stream<T> s) {
Spliterator<T> sp = s.spliterator();
return StreamSupport.stream(new Spliterators.AbstractSpliterator<T>(
sp.estimateSize(), sp.characteristics() & ~Spliterator.SIZED) {
boolean dropped;
public boolean tryAdvance(Consumer<? super T> action) {
if(dropped) return sp.tryAdvance(action);
do {} while(!dropped && sp.tryAdvance(t -> {
if(!p.test(t)) {
dropped=true;
action.accept(t);
}
}));
return dropped;
}
public void forEachRemaining(Consumer<? super T> action) {
while(!dropped) if(!tryAdvance(action)) return;
sp.forEachRemaining(action);
}
}, s.isParallel());
}
這種方法可以使用方式與第dropWhile
方法相同,但它的工作即使並行流,因爲你米,雖然效率不高願望。
不幸的是,使用Java 8的唯一方法是使用由Holger提供的解決方案。
但是,操作dropWhile(predicate)
一直added to Java 9所以從JDK 9日起,你可以簡單地有:
Stream.of(0, 1, 2, 3, 0, 1, 2, 3, 4).dropWhile(n -> n < 3).forEach(System.out::println);
相關:限制由一個謂語流(http://stackoverflow.com/q/ 20746429) – charlie 2016-06-28 12:31:06