🌐
Medium
medium.com › @AlexanderObregon › javas-stream-limit-method-explained-b1f872252828
Java’s Stream.limit() Method Explained | Medium
January 14, 2025 - For example, when reading large files, you may want to process only the first few lines to avoid loading the entire file into memory: import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; public class ...
🌐
HowToDoInJava
howtodoinjava.com › home › java 8 › java stream limit()
Java Stream limit() with Example - HowToDoInJava
March 30, 2022 - List<Integer> list = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) .skip(6) .collect(Collectors.toList()); System.out.println(newList); //[7, 8, 9, 10] Java 8 Stream limit() method can be useful in certain cases where we need to get the elements ...
🌐
GeeksforGeeks
geeksforgeeks.org › java › stream-limit-method-in-java
stream.limit() method in Java - GeeksforGeeks
August 27, 2024 - Stream<T> limit(long N) Where N is the number of elements the stream should be limited to and this function returns new stream as output. ... If the value of N is negative, then IllegalArgumentException is thrown by the function.
🌐
Baeldung
baeldung.com › home › java › java streams › java stream skip() vs limit()
Java Stream skip() vs limit() | Baeldung
January 8, 2024 - In this brief article, we’ve shown the similarities and differences of the skip() and limit() methods of the Java Stream API. We’ve also implemented some simple examples to show how we can use these methods.
🌐
ConcretePage
concretepage.com › java › java-8 › java-stream-limit
Java Stream limit()
May 8, 2024 - Find the limit method declaration from Java doc. Stream<T> limit(long maxSize) The parameter maxSize is the max number of elements in the stream returned by limit. The limit method returns new Stream.
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › stream › Stream.html
Stream (Java Platform SE 8 )
3 weeks ago - Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length. This is a short-circuiting stateful intermediate operation. ... While limit() is generally a cheap operation on sequential stream pipelines, it can be quite expensive on ordered parallel pipelines, especially for large values of maxSize, since limit(n) is constrained to return not just any n elements, but the first n elements in the encounter order.
🌐
DEV Community
dev.to › realnamehidden1_61 › how-does-the-limit-method-differ-from-the-skip-method-in-streams-3lgg
How does the limit() method differ from the skip() method in streams? - DEV Community
December 8, 2024 - List<Integer> numbers = List.of(1, 2, 3, 4, 5); List<Integer> skipped = numbers.stream() .skip(2) .collect(Collectors.toList()); System.out.println(skipped); // Output: [3, 4, 5] ... Ignoring initial elements in processing.
🌐
DEV Community
dev.to › realnamehidden1_61 › java-8-stream-api-limit-and-skip-methods-46kl
Java 8 Stream API limit() and skip() methods - DEV Community
November 2, 2024 - limit(n): Limits the stream to the first n elements. skip(n): Skips the first n elements and processes the rest. ... import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class StreamLimitSkipExample { public ...
Find elsewhere
🌐
JRebel
jrebel.com › blog › java-streams-in-java-8
Using Java Streams in Java 8 and Beyond | JRebel by Perforce
The example above shows one of the most important pattern you’ll end up using with the streams: Raise a collection to a stream. Ride the stream: filter values, transform values, limit the output. Compose small individual operations. Collect the result back into a concrete collection.Back to top · In Java ...
🌐
TutorialsPoint
tutorialspoint.com › intstream-limit-method-in-java
IntStream limit() method in Java
Now, use the limit() method, whose ...eam.IntStream; public class Demo { public static void main(String[] args) { IntStream intStream = IntStream.range(20, 40); intStream.limit(8).forEach(System.out::println); } }...
🌐
ZetCode
zetcode.com › java › stream-limit
Java Stream limit - Truncating Streams
May 25, 2025 - This example finds numbers divisible by 3 but limits the result to the first 5 matches (3, 6, 9, 12, 15). A common use case for limit is retrieving the top N results from a processed stream, such as the highest values or most relevant items.
🌐
Java Guides
javaguides.net › 2024 › 04 › java-stream-limit-example.html
Java Stream limit() Example
April 27, 2024 - ... import java.util.List; import ... public static void main(String[] args) { // Stream of integers Stream<Integer> numberStream = Stream.iterate(1, n -> n + 1); // Limiting the stream to the first 5 elements List<Integer> ...
🌐
GeeksforGeeks
geeksforgeeks.org › java › intstream-limit-java
IntStream limit() in Java - GeeksforGeeks
July 11, 2025 - Example 1 : ... // Java code for ... public static void main(String[] args) { // Creating an IntStream IntStream stream = IntStream.of(2, 4, 6, 8, 10); // Using IntStream limit(long maxSize) to // get a stream consisting of ...
Top answer
1 of 5
106

What you have here are two stream pipelines.

These stream pipelines each consist of a source, several intermediate operations, and a terminal operation.

But the intermediate operations are lazy. This means that nothing happens unless a downstream operation requires an item. When it does, then the intermediate operation does all it needs to produce the required item, and then again waits until another item is requested, and so on.

The terminal operations are usually "eager". That is, they ask for all the items in the stream that are needed for them to complete.

So you should really think of the pipeline as the forEach asking the stream behind it for the next item, and that stream asks the stream behind it, and so on, all the way to the source.

With that in mind, let's see what we have with your first pipeline:

Stream.of(1,2,3,4,5,6,7,8,9)
        .peek(x->System.out.print("\nA"+x))
        .limit(3)
        .peek(x->System.out.print("B"+x))
        .forEach(x->System.out.print("C"+x));

So, the forEach is asking for the first item. That means the "B" peek needs an item, and asks the limit output stream for it, which means limit will need to ask the "A" peek, which goes to the source. An item is given, and goes all the way up to the forEach, and you get your first line:

A1B1C1

The forEach asks for another item, then another. And each time, the request is propagated up the stream, and performed. But when forEach asks for the fourth item, when the request gets to the limit, it knows that it has already given all the items it is allowed to give.

Thus, it is not asking the "A" peek for another item. It immediately indicates that its items are exhausted, and thus, no more actions are performed and forEach terminates.

What happens in the second pipeline?

    Stream.of(1,2,3,4,5,6,7,8,9)
    .peek(x->System.out.print("\nA"+x))
    .skip(6)
    .peek(x->System.out.print("B"+x))
    .forEach(x->System.out.print("C"+x));

Again, forEach is asking for the first item. This is propagated back. But when it gets to the skip, it knows it has to ask for 6 items from its upstream before it can pass one downstream. So it makes a request upstream from the "A" peek, consumes it without passing it downstream, makes another request, and so on. So the "A" peek gets 6 requests for an item and produces 6 prints, but these items are not passed down.

A1
A2
A3
A4
A5
A6

On the 7th request made by skip, the item is passed down to the "B" peek and from it to the forEach, so the full print is done:

A7B7C7

Then it's just like before. The skip will now, whenever it gets a request, ask for an item upstream and pass it downstream, as it "knows" it has already done its skipping job. So the rest of the prints are going through the entire pipe, until the source is exhausted.

2 of 5
13

The fluent notation of the streamed pipeline is what's causing this confusion. Think about it this way:

limit(3)

All the pipelined operations are evaluated lazily, except forEach(), which is a terminal operation, which triggers "execution of the pipeline".

When the pipeline is executed, intermediary stream definitions will not make any assumptions about what happens "before" or "after". All they're doing is take an input stream and transform it into an output stream:

Stream<Integer> s1 = Stream.of(1,2,3,4,5,6,7,8,9);
Stream<Integer> s2 = s1.peek(x->System.out.print("\nA"+x));
Stream<Integer> s3 = s2.limit(3);
Stream<Integer> s4 = s3.peek(x->System.out.print("B"+x));

s4.forEach(x->System.out.print("C"+x));
  • s1 contains 9 different Integer values.
  • s2 peeks at all values that pass it and prints them.
  • s3 passes the first 3 values to s4 and aborts the pipeline after the third value. No further values are produced by s3. This doesn't mean that no more values are in the pipeline. s2 would still produce (and print) more values, but no one requests those values and thus execution stops.
  • s4 again peeks at all values that pass it and prints them.
  • forEach consumes and prints whatever s4 passes to it.

Think about it this way. The whole stream is completely lazy. Only the terminal operation actively pulls new values from the pipeline. After it has pulled 3 values from s4 <- s3 <- s2 <- s1, s3 will no longer produce new values and it will no longer pull any values from s2 <- s1. While s1 -> s2 would still be able to produce 4-9, those values are just never pulled from the pipeline, and thus never printed by s2.

skip(6)

With skip() the same thing happens:

Stream<Integer> s1 = Stream.of(1,2,3,4,5,6,7,8,9);
Stream<Integer> s2 = s1.peek(x->System.out.print("\nA"+x));
Stream<Integer> s3 = s2.skip(6);
Stream<Integer> s4 = s3.peek(x->System.out.print("B"+x));

s4.forEach(x->System.out.print("C"+x));
  • s1 contains 9 different Integer values.
  • s2 peeks at all values that pass it and prints them.
  • s3 consumes the first 6 values, "skipping them", which means the first 6 values aren't passed to s4, only the subsequent values are.
  • s4 again peeks at all values that pass it and prints them.
  • forEach consumes and prints whatever s4 passes to it.

The important thing here is that s2 is not aware of the remaining pipeline skipping any values. s2 peeks at all values independently of what happens afterwards.

Another example:

Consider this pipeline, which is listed in this blog post

IntStream.iterate(0, i -> ( i + 1 ) % 2)
         .distinct()
         .limit(10)
         .forEach(System.out::println);

When you execute the above, the program will never halt. Why? Because:

IntStream i1 = IntStream.iterate(0, i -> ( i + 1 ) % 2);
IntStream i2 = i1.distinct();
IntStream i3 = i2.limit(10);

i3.forEach(System.out::println);

Which means:

  • i1 generates an infinite amount of alternating values: 0, 1, 0, 1, 0, 1, ...
  • i2 consumes all values that have been encountered before, passing on only "new" values, i.e. there are a total of 2 values coming out of i2.
  • i3 passes on 10 values, then stops.

This algorithm will never stop, because i3 waits for i2 to produce 8 more values after 0 and 1, but those values never appear, while i1 never stops feeding values to i2.

It doesn't matter that at some point in the pipeline, more than 10 values had been produced. All that matters is that i3 has never seen those 10 values.

To answer your question:

Is it just that "every action before skip is executed while not everyone before limit is"?

Nope. All operations before either skip() or limit() are executed. In both of your executions, you get A1 - A3. But limit() may short-circuit the pipeline, aborting value consumption once the event of interest (the limit is reached) has occurred.

🌐
Netjstech
netjstech.com › 2021 › 09 › java-stream-limit-with-examples.html
Java Stream - limit() With Examples | Tech Tutorials
March 5, 2024 - 1. Getting a sublist from a List by limiting the number of elements to the first n elements of the original list. import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class StreamLimit { public static void main(String[] args) { StreamLimit sl = new ...
🌐
Medium
medium.com › @rihab.beji099 › understanding-limit-in-java-stream-for-kids-c6d22078ab80
Understanding .limit() in Java stream for Kids | by Rihab Beji | Medium
October 29, 2024 - Think of a stream as a flowing river of candies (or any items) that you can work with. With .limit(), you can tell Java, “I only want this many items from my stream!”
🌐
Kodejava
kodejava.org › how-do-i-use-limit-method-in-java-stream-api
How do I use limit method in Java Stream API? - Learn Java by Examples
... package org.kodejava.stream; ... void main(String[] args) { Stream<Integer> numbersStream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9); numbersStream .limit(4) .forEach(System.out::println); } }...
🌐
Javaprogramto
javaprogramto.com › 2020 › 08 › java-8-stream-limit-method-example.html
Java 8 Stream limit() Method Example JavaProgramTo.com
August 17, 2020 - Use Java 8 Stream.limit() method to retrieve only the first n objects and setting the maximum size. And it ignores the remaining values after size n.
🌐
Apps Developer Blog
appsdeveloperblog.com › home › java › functional programming in java › streams – limit() and skip() operations
Java Stream limit() and skip() operations
August 10, 2022 - class Test { public static void main(String[] args) { List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); List<Integer> resultList = numbers.stream() .limit(5) .map(num -> num * 2) .collect(Collectors.toList()); System.out.println(resultList); } }