< prev index next >
src/java.base/share/classes/java/util/stream/Stream.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 1203,1212 ****
--- 1203,1279 ----
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE), false);
}
/**
+ * Returns a sequential ordered {@code Stream} produced by iterative
+ * application of a function {@code f} to an initial element {@code seed},
+ * producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
+ * {@code f(f(seed))}, etc. The stream terminates when {@code predicate}
+ * returns false.
+ *
+ * <p>The first element (position {@code 0}) in the {@code Stream} will be
+ * the provided {@code seed}. For {@code n > 0}, the element at position
+ * {@code n}, will be the result of applying the function {@code f} to the
+ * element at position {@code n - 1}.
+ *
+ * @param <T> the type of stream elements
+ * @param seed the initial element
+ * @param predicate a predicate to apply to elements to determine when the
+ * stream must terminate.
+ * @param f a function to be applied to the previous element to produce
+ * a new element
+ * @return a new sequential {@code Stream}
+ * @since 9
+ */
+ public static<T> Stream<T> iterate(T seed, Predicate<T> predicate, UnaryOperator<T> f) {
+ Objects.requireNonNull(f);
+ Objects.requireNonNull(predicate);
+ Spliterator<T> spliterator = new Spliterators.AbstractSpliterator<T>(Long.MAX_VALUE,
+ Spliterator.ORDERED | Spliterator.IMMUTABLE) {
+ T prev;
+ boolean started, finished;
+
+ @Override
+ public boolean tryAdvance(Consumer<? super T> action) {
+ Objects.requireNonNull(action);
+ if (finished)
+ return false;
+ T t;
+ if (started)
+ t = f.apply(prev);
+ else {
+ t = seed;
+ started = true;
+ }
+ if (!predicate.test(t)) {
+ prev = null;
+ finished = true;
+ return false;
+ }
+ action.accept(prev = t);
+ return true;
+ }
+
+ @Override
+ public void forEachRemaining(Consumer<? super T> action) {
+ Objects.requireNonNull(action);
+ if (finished)
+ return;
+ T t = started ? f.apply(prev) : seed;
+ finished = true;
+ prev = null;
+ while (predicate.test(t)) {
+ action.accept(t);
+ t = f.apply(t);
+ }
+ }
+ };
+ return StreamSupport.stream(spliterator, false);
+ }
+
+ /**
* Returns an infinite sequential unordered stream where each element is
* generated by the provided {@code Supplier}. This is suitable for
* generating constant streams, streams of random elements, etc.
*
* @param <T> the type of stream elements
< prev index next >