Limit a stream by a predicate
Operations takeWhile
and dropWhile
have been added to JDK 9. Your example code
IntStream
.iterate(1, n -> n + 1)
.takeWhile(n -> n < 10)
.forEach(System.out::println);
will behave exactly as you expect it to when compiled and run under JDK 9.
JDK 9 has been released. It is available for download here: JDK 9 Releases.
Stream generate until a limit but only matching a predicate
Like this:
List<Integer> list = Stream.generate(new Random()::nextInt)
.filter(p -> p > 10)
.limit(100).collect(Collectors.toList());
Or like this one:
public class Main {
private static boolean isBig(Integer input) {
return input > 10;
}
public static void main(String args[]) {
List<Integer> list = Stream.generate(new Random()::nextInt)
.filter(Main::isBig)
.limit(100).collect(Collectors.toList());
}
}
Can I count my stream size if I limit it by a predicate dependent on the input?
Java 9 has a feature to support that - takeWhile:
random.ints(0, Integer.MAX_VALUE).takeWhile(a -> a < 20000).count();
Is there a way to stop Stream.iterate() with a predicate?
Using Java-9 or above, one way is to use Stream.takeWhile
as:
Stream.iterate(1, i -> i * 2) // notice identity value in seed
.takeWhile(i -> i < MAX)
Another alternative is to use Stream.iterate
Stream.iterate(1, i -> i < MAX, i -> i * 2)
Limit a stream and find out if there are pending elements
I don't think there's a nice way to do this. I've found a hack that does it lazily. What you can do is convert the Stream
to an Iterator
, convert the Iterator
back to another Stream
, do the Stream
operations, then finally test the Iterator
for a next element!
Iterator<SomeResource> it = this.someResource().iterator();
List<String> list = StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.ORDERED), false)
.filter(resource -> !resource.isTaken())
.limit(MAX_TO_RELEASE)
.peek(SomeResource::release)
.map(SomeResource::getName)
.collect(Collectors.toList());
return new ReleaseResult(list, it.hasNext(), MAX_TO_RELEASE);
jenetics: Set EvolutionStream limit outside of stream()
The EvolutionStream.limit(Predicate)
method does return an EvolutionStream
.
EvolutionStream<IntegerGene, Double> stream = engine.stream();
stream = stream
.limit(Limits.byFixedGeneration(10))
.limit(Limits.bySteadyFitness(5))
.limit(Limits.byExecutionTime(Duration.ofMillis(100)));
So your given examples look good and should work. But the EvolutionStream.limit(Predicate)
method is the only method which gives you back an EvolutionStream
.
An alternative would be that your method, which initializes the EvolutionStream
, takes the Predicate
s from outside.
@SafeVarargs
static EvolutionStream<IntegerGene, Double>
newStream(final Predicate<? super EvolutionResult<IntegerGene, Double>>... limits) {
final Engine<IntegerGene, Double> engine = Engine
.builder(a -> a.gene().allele().doubleValue(), IntegerChromosome.of(0, 100))
.build();
EvolutionStream<IntegerGene, Double> stream = engine.stream();
for (var limit : limits) {
stream = stream.limit(limit);
}
return stream;
}
final var stream = newStream(
Limits.byFixedGeneration(100),
Limits.byExecutionTime(Duration.ofMillis(1000)),
Limits.bySteadyFitness(10)
);
What happens if I'll call limit() after filter() from Stream API?
filter()
has lazy execution. This means that it doesn't actually do anything right when you call it. Instead it just returns a new Stream
that will contain the elements that match the given Predicate
when traversed.
Since limit()
is a short-circuiting stateful intermediate operation, it will process the Stream
until it reaches the limit and short circuits. This means that when you call filter
, it will return a new Stream that contains only the elements, when traversed. Since limit
only traverses enough to reach the given size, filter
will, in effect, only filter out the required amount of elements.
We can test this by throwing in a call to peek()
:
Arrays.stream(new int[] {1, 2, 2, 2, 2})
.filter(e-> e > 1)
.peek(System.out::println)
.limit(3)
.average();
(Where average()
could be any terminal operation that doesn't short circuit on its own)
Which outputs:
2
2
2
(Note that the last two does not appear after the call to filter()
)
Java IntStream or LongStream limit by value and not by count of elements
In Java 9+, use takeWhile(i -> i <= value)
.
Related Topics
Java.Net.Connectexception: Connection Refused
Java Process With Input/Output Stream
Http Url Address Encoding in Java
How to Add Blank Page in Digitally Signed Pdf Using Java
How Can a Java Program Get Its Own Process Id
Array or List in Java. Which Is Faster
Method Has the Same Erasure as Another Method in Type
How to Convert Int[] into List≪Integer≫ in Java
Intersection and Union of Arraylists in Java
How to Make an Executable Jar File
How to Parse/Format Dates With Localdatetime - Java 8
"Missing Return Statement" Within If/For/While
How Does the "Final" Keyword in Java Work (I Can Still Modify an Object.)
What Does the ^ Operator Do in Java