Repository navigation
Typos and possible small errors in the Streams articles ( https://dev.java/learn/api/streams/ ) #200
Description
Hello dev.java team!
Thanks for the excellent https://dev.java/learn/api/streams/ series of articles on Java Streams.
I would like to report a few typos and other small possible mistakes.
In the latest version of article "Adding a Terminal Operation on a Stream", https://dev.java/learn/api/streams/terminal-operations/ (archived at https://web.archive.org/web/20260225004953/https://dev.java/learn/api/streams/terminal-operations/ ):
- A verbatim duplicated code block is introduced with the expectation of being distinct.
After the code block:
Stream<String> strings = Stream.of("one", "two", "three", "four");
List<String> result =
strings.filter(s -> s.length() == 3)
.map(String::toUpperCase)
.toList();
IO.println("result = " + result);
is presented,
it is said "Starting with Java SE 16, you have a second, even simpler, pattern."
followed by a code block with:
Stream<String> strings = Stream.of("one", "two", "three", "four");
List<String> result =
strings.filter(s -> s.length() == 3)
.map(String::toUpperCase)
.toList();
IO.println("result = " + result);
Which is identical, and thus cannot be "even simpler", suggesting this was repeated in error, see screenshot below:
Maybe the first block was supposed to use ".collect(Collectors.toList())" and the 2nd block ".toList()" (which is newer and simpler)?
However, the article also says the first pattern produces a modifiable list in contrast to the 2nd, but in fact .collect(Collectors.toList()), while not guaranteed to produce an unmodifiable list (unlike .toList),
has no guarantee on modifiability at all, with the documentation stating "there are no guarantees on the type, mutability, serializability, or thread-safety of the List returned; if more control over the returned List is required, use toCollection(Supplier)." (https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/stream/Collectors.html#toList() ).
So the sentence "If what you need is a modifiable list, you should stick to the first collector pattern" must be referring to something else, like .forEach(someList::add) for a manually created mutable list, someList, or should refer to Collectors.toCollection .
-
In the next section, when introducing the ".collect(Collectors.toList())" approach, the text states "You already used this pattern in a previous example", when no previous example in this article used this approach. (This also suggests that in the duplicated block above, maybe one of the blocks was intended to be using ".collect(Collectors.toList())" instead of ".toList()"? I think .toList() came in SE 16, so maybe that was supposed to be the second example and ".collect(Collectors.toList())" the first?)
-
Not a mistake, but repetition worth reviewing for possible consolidation:
"Starting with Java SE 16, there is a better way to collect your data in an immutable list, which can be more efficient on some cases. [Same code block as presented 2x above, showing Stream.toList() again]"
"This optimization has been implemented in the Stream.toList() method, which has been added to Java SE 16. If what you need is an immutable list, then you should be using this pattern." -
Re: "The supplier you used to tune the initial size of you instance of ArrayList can also be used to build any implementation of Collection, including implementations that are not part of the JDK."
In "used to tune the initial size of you instance", "you instance" should be "your instance". -
Re: "We already covered the max() and min() methods from the specialized streams of numbers: IntStream, LongStream and DoubleStream. You know that these operations do not have an identity element, so you should not be surprised to discover that there are all returning optional objects."
"there are all returning optional objects" should be "they are all returning optional objects" -
In "You may have noticed an important difference between the different terminal operation that we have covered here.", "operation" should be plural.
In the latest version of the "Creating Streams" article, https://dev.java/learn/api/streams/creating/ (as archived at https://web.archive.org/web/20260224131949/https://dev.java/learn/api/streams/creating/ ):
-
In the sentence "The random numbers depends on that seed", "depends" should be "depend".
-
Potentially confusing:
random.ints()described with a range which might not be recognized as matching the code
(endpoints excluded range; English typically uses endpoints inclusive; and the APIs, including Random.ints(), half-open / half-closed intervals, specifically right-open aka start-inclusive-end-exclusive)
Specifically, it is written "Here is a first pattern of code that generates 10 random integers between 0 and 5."
when the associated code snippet uses
random.ints(10, 1, 5)
.boxed()
.toList();
which would return random integers between 1 (inclusive) and 5 (exclusive) (the right-open interval [1, 5)), which is between 0 and 5 only if both endpoints are treated as exclusive (open integer interval (0, 5)) (the text does not specify that both endpoints are excluded).
Endpoints excluded integer intervals/ranges are unusual in both plain English (typically inclusive) and programming (typically half-open / half-closed).
E.g. the Java language specification v25 in English gives numeric ranges typically inclusive, like "an integer between [Emin] and [Emax], inclusive" or "the components of the array are referenced using integer indices from 0 to n - 1, inclusive" or "the shift distance actually used is therefore always in the range 0 to 31, inclusive", etc, while the Java APIs usually use half-open / half-closed intervals (which combine well without double counting), e.g. as in the API used here Random.ints() but also String.substring(), Time APIs like Duration.between, or many other places.
(Many applications use half-open intervals (typically right-open inclusive-exclusive) as any interval can be subdivided easily into half-open intervals without overlap or double counting; intervals excluding both endpoints do not combine well and are usually not used; that is e.g. the right-open interval [1, 3) can be combined with [3, 5) to intuitively get the new half-open interval spanning both, [1, 5). Whereas combining open intervals (both endpoints excluded) with the same endpoints does not even result in an interval, e.g. (1,3) combined with (3, 5) gives the disconnected integers 2 and 4 ({2, 4})).
-
"Being able to process these lines with the Stream API gives you a more readable and more maintainable code."
"gives you a more readable and more maintainable code" should be "gives you more readable and maintainable code" -
"To run it, you need to copy it, paste it in your IDE, and adjust de path to fit your local installation."
"adjust de path" should be "adjust the path" -
"Note that you cannot run this code in your brower." "brower" should be "browser".
In the latest version of an article "Reducing a Stream", https://dev.java/learn/api/streams/reducing/ (archived at https://web.archive.org/web/20260224224658/https://dev.java/learn/api/streams/reducing/ )
-
In the sentence "There are two caveats you need to understand though. Let us the first one here and the second one in the next section. ",
"Let us the first one here" is missing a word after "us". Maybe it was intended to read "Let us discuss the first one here" or something similar. -
Re: "A way to check for that property can be just to run your binary operator on random data and verify if you always get the same result. If you do not, then you know your binary operator is not associative. If you do, then, unfortunately, you cannot conclude reliably." Not a mistake but the last sentence seems unclear. It might be clearer if the last sentence were replaced with something like "If you do, then the operator might be associative but it still may not be, as such a result is inconclusive."
-
Re: "Let us an example with a reduction that does not have an identity element."
"Let us an" should be "Let us do an". -
Re: "The combiner combines two integers: the partial sums of the lengths of the strings processed so far. So the identity element you need to provide is the identity element: O."
"O" should be the number "0". -
In the sentence: "This way of writing thing clearly shows the fusion of the mapping, modeled by the mapper and the reduction, modeled by the binary operator":
"thing" should be "things", and I think there should be a comma after "mapper".
In the latest version of the article "Adding Intermediate Operations on a Stream", https://dev.java/learn/api/streams/intermediate-operation/ (archived at https://web.archive.org/web/20260224062952/https://dev.java/learn/api/streams/intermediate-operation/ ),
-
In the sentence, "This mapToInt() method takes a ToIntFuction as an argument." , "ToIntFuction" should be "ToIntFunction"
-
Under "Filtering a Stream",
"This method is available on streams of objects and stream of primitive types." , it should read "and streams of primitive types" with a plural streams for both types of streams.
In the next example's code block it is written:
Country uk = new Country("United Kindgom", List.of(london, manchester));
with a typo in "United Kindgom".
- Re: "The reason why it is better to use the flatMap() way is that concat() creates intermediates streams during the concatenation." This should use "intermediate" instead of "intermediates".
Thanks so much for all this content!
(If these typo/error reports continue to be desired, it is fine to leave this issue open even after fixing what is reported above so I can add any additional items found, as I am still working through the Streams articles.)
Activity
JosePaumard commentedon Feb 25, 2026
Thank you Willy for your report! I just pushed a fix.
As for the collect(Collectors.toList()). It is not stated that it returns an ArrayList. But it does, and changing this implementation would be a breaking change. It is now set in stone, it will never change. Especially to a list that would be non-modifiable.
And yes, you can totally keep sending reports, many thanks for them!
willy-b commentedon Feb 26, 2026
Great! Here's another batch of little issues found in these Streams articles.
In the "Using Collectors" article at https://dev.java/learn/api/streams/using-collectors (archived at https://web.archive.org/web/20260225070958/https://dev.java/learn/api/streams/using-collectors/ ),
produces a result that does not match that description (includes non-evens).
The following code snippet is shown:
with output:
Which are not all even numbers, e.g. 1 and 3 are included.
The result is without duplicates,
but to give even numbers, it would need to be updated, one way would be to have
.filter(number -> number % 2 == 0)instead of.map(number -> number / 2).An updated version of the code could be:
e.g.:
In the sentence, "The first one we cover creates map with boolean keys. It is created with the partitionningBy() factory method. "
"creates map" should be "creates a map", and "partitionningBy()" should be "partitioningBy()".
In the sentence, "The collector you can use to create histogram is created with the Collectors.groupingBy() method", "to create histogram" should be "to create histograms".
In the sentence, "The groupingBy() collector supports this, and gather all these elements in a list, bound to that key. ", "and gather all" should be "and gathers all"
In the sentence, "Let examine the following example.", "Let examine" should be "Let us examine"
In the sentence, "
(element1, element2) -> element1 + ", " + element2)is the merge function, called with the two elements that have generated the same key."there is an extra
)at the end of the lambdaIn the sentence, "The Collectors.mappping() factory method creates a regular collector." , "Collectors.mappping()" should be "Collectors.mapping()"
In the article on "Finding the Characteristics of a Stream", https://dev.java/learn/api/streams/characteristics/ (archived at: https://web.archive.org/web/20260225071047/https://dev.java/learn/api/streams/characteristics/ ),
In the sentence, "Covering this spliterator object in details is beyond the scope of this tutorial", "in details" should be "in detail".
In the sentence, "Let us present each characteristic in more details", it seems "details" should be "detail."
In the sentence "To check is a stream has a given characteristics, you need to check for a given bit in a word within the spliterator of a stream"
"To check is a stream has a given characteristics" should probably read "To check IF a stream has given characteristics",
and "check for a given bit in a word within the spliterator of a stream" might be replaced with "call the
hasCharacteristics()method of the spliterator of the stream with the characteristic values to check or directly check for a given bit within the bitmap returned by the.characteristics()method"In the sentence "Keeping track of the order of the elements of a stream may lead to overheads for parallel streams", "overheads" should be "overhead."
In the sentence "strings.stream() is not DISTINCT as it is build from an instance of List.", "as it is build from" should be "as it is built from."
In the text, "the parallelization mechanism splits a stream in two parts and distribute the computation", (1) "distribute" should be "distributes" and (2) it might be an improvement to write "splits a stream INTO two parts" instead of "in two parts", but (2) is a matter of taste.
In the sentence, "It is always better to have SIZED and SUBSIZED stream for parallel computations.", "stream" should be "streams".
Thanks!
JosePaumard commentedon Feb 26, 2026
Thank you again for your report! I just pushed a fix.
I rephrased the part on the characteristic, I hope it's more clear as it is.
willy-b commentedon Feb 26, 2026
Thanks! (and N.B. I do reply re: the spliterator change in the 2nd block below.)
Note, FYI, you have still not yet fixed or replied re: the "evenNumbers" example in the "Using Collectors" article at https://dev.java/learn/api/streams/using-collectors (archived: https://web.archive.org/web/20260226143455/https://dev.java/learn/api/streams/using-collectors/ ) reported in the last comment.
produces a result that does not match that description (includes non-even numbers, e.g. 1 and 3).
See screenshot, details, and a suggested fix in my comment above at #200 (comment) . (Note that 0 is fine to include in the even numbers, per e.g. https://oeis.org/A005843 or https://web.archive.org/web/20260226161619/https://mathworld.wolfram.com/EvenNumber.html , but not 1 and 3 as the team's article's code also outputs in that example).
introduces an example of computing the maximum key-value pair of the map produced by groupingBy on a stream,
and solves it two ways:
(1) using a generic Map.Entry comparator (.comparingByValue()) with the Stream.max operation
(2) using a custom record with a custom comparator method (record class NumberOfLength with comparingByLength())
It is not clear whether it is intentional that when comparing the two methods to find the "Non-Ambiguous Max", approach (1) takes the maximum comparing values of the key-value pairs (in this case the number of strings with a certain length), and approach (2) switches to comparing keys (string lengths observed, for which counts were accumulated).
This seems unintentional, like if the author's mind changed and they did not update consistently, since the problem is introduced clearly as computing the maximum using the value of the key value pair (finding string length which was most frequent), e.g.:
The solution using approach (1) gives "3 :: 4" , but then for (2) the criterion is switched, not just the methodology, so that the result "6 :: 2" is produced instead.
Additional evidence it might be unintentional that the criterion switched is in the next sentence after the conclusion of that example, which says "The previous example was a nice example, because there was only one maximum value in your list. "
Yes, re: the spliterator, in the sentence that originally read
where I had commented above:
You have updated it to
This is fine by me! I still think it may be worth mentioning the
hasCharacteristics(int)method which can be used with e.g. Spliterator.DISTINCT, Spliterator.ORDERED, or some combination of these, etc, but I am fine with how it is now.Referring to the int as a word is obviously ok (e.g. this terminology is even used in the JVM spec v25 ( https://docs.oracle.com/javase/specs/jvms/se25/jvms25.pdf ) section 4.10.1.2 which explains how the type "oneWord" is the supertype of int, float, and reference and it is clear from this context that out of those 3 it must be int ).
Re: https://dev.java/learn/api/streams/terminal-operations/ ,
Thanks for the updates to multiple sections, but especially the "Consuming Each Element One by One" section of https://dev.java/learn/api/streams/terminal-operations/ (archived: https://web.archive.org/web/20260226200825/https://dev.java/learn/api/streams/terminal-operations/#foreach ) , as the repeated block I reported earlier ( #200 (comment) ) has been replaced, and it has been re-written in a very clear way generally, comparing and contrasting
.collect(Collectors.toList())and.toList()instead of repeating two.toList()examples back to back unintentionally (compare with previous version https://web.archive.org/web/20260225004953/https://dev.java/learn/api/streams/terminal-operations/#foreach ).Another two items not yet fixed or replied to though reported above in #200 (comment):
still present in the latest version of the "Creating Streams" article , https://dev.java/learn/api/streams/creating/ (archived at https://web.archive.org/web/20260226163311/https://dev.java/learn/api/streams/creating/ ) :
where "gives you a more readable and more maintainable code" should be "gives you more readable and maintainable code" .
still present in the latest https://dev.java/learn/api/streams/reducing/ (archived at https://web.archive.org/web/20260226045520/https://dev.java/learn/api/streams/reducing/ ) :
"Let us an" should be "Let us do an".
Then, in the latest version of "Creating Your Own Collector", https://dev.java/learn/api/streams/custom-collectors/ (archived at
https://web.archive.org/web/20260225071030/https://dev.java/learn/api/streams/custom-collectors/ ):
Re: "In a first step, you built an histogram of type Map<Inter, Long>,", "Map<Inter, Long>" should probably be "Map<Integer,Long>".
Re: "Let us go through a use case to see what you can do with collector." "collector" should be "collectors".
In the first code block introducing the Vehicle interface and Car and Truck records, it is described in the text that Car and Truck implement Vehicle
but the "implements Vehicle" is apparently accidentally omitted from the record declarations (in the subsequent example code block that uses Car and Truck, it is fixed)
"It is still possible create this union" should be "It is still possible TO create this union";
"on one pass your collection" should be "on one pass of your collection"
Thanks very much!
JosePaumard commentedon Feb 27, 2026
Thank you again for your report! I just pushed a fix.
I am a little worried, because some of the fixes that I did apparently didn't make it to the live site. So I pushed them again, I hope it will work this time.
willy-b commentedon Mar 19, 2026
Thanks so much!
I can confirm I can now see the added example showing alternatively how to use the Spliterator.hasCharacteristics method as discussed above ( https://web.archive.org/web/20260318235843/https://dev.java/learn/api/streams/characteristics/ ) and that the "Extracting a Non-Ambiguous Max" example has been fixed as of https://web.archive.org/web/20260318231310/https://dev.java/learn/api/streams/using-collectors/ .
But, indeed it does seem some of your intended updates are not yet showing on the live site (see below).
For https://dev.java/learn/api/streams/using-collectors/ ,
The source code was updated but not the expected output for the example previously on "evenNumbers" (it now has a different intended output vs https://web.archive.org/web/20260226143455/https://dev.java/learn/api/streams/using-collectors/ ).
E.g. as archived today https://web.archive.org/web/20260318231310/https://dev.java/learn/api/streams/using-collectors/ ,
it still shows the code snippet output as:
Also, re: the "Combining the Results of Two Collectors with the Teeing Collector" section of https://dev.java/learn/api/streams/custom-collectors/ (archived as is in https://web.archive.org/web/20260318235113/https://dev.java/learn/api/streams/custom-collectors/ ), which does not show in the sidebar as a section despite being a H2 like other sections, as reported earlier
the
implements Vehicle(Vehicle being an empty interface) has not been added to the first Car/Truck examples yet onteeingonly the second (appears accidental).Then, presumably the
Vehicleinterface is empty of methods intentionally to contrive an excuse for usingteeing, but it may be observed that since both record classes include the record component "engine" of the same type (and also "drive"),the
teeingexample could be updated to include the accessor methods for those common components for the Car and Truck in the Vehicle interface:then the teeing code could be simplified from using instanceof checks for Car or Truck to call the common method "engine()":
(existing version)
to call this method on the Vehicle interface, which obviates using
teeingat all, allowing use of plain.filter():It might be didactic to also show that approach to highlight how teeing might not always be the best solution.
Thanks!
JosePaumard commentedon Mar 20, 2026
Thank you again for yout report! I just pushed a fix.
As for the teeing() Collector: I updated the example to use a sealed interface. The idea behind that it to stay within the Data Oriented Programming ideas, and avoiding adding any behavior on the sealed types. If you add a vehicle later that does not have the behavior you put in the interface, then the refactoring will be much harder.
Now I know that this example is not great and needs some attention. There are limitations in the Playground (one cannot use java.io for instance) that makes the crafting of these examples trickier.
willy-b commentedon Apr 14, 2026
Great! Thanks for the updates!
And thanks for your patience, since my last comment here I have been working on #210 on the File Systems tutorial, #206 on the Collections Framework tutorial, #218 on the Garbage Collection tutorial, #211 on the Classes and Objects tutorial, #215 on the Switch tutorial (and others) in parallel.
Re: the "Combining the Results of Two Collectors with the Teeing Collector" section of https://dev.java/learn/api/streams/custom-collectors/ ,
and your choice using
teeing()without noting that one could instead add an abstractengine()method to the interface (Records can override interface methods with their accessors) to simplify, I just wanted in my last comment to show the stream filtering in that case could be done in one line (givenengine()added toVehicleinterface:vehicles.stream().filter(vehicle -> vehicle.engine() == Engine.ELECTRIC).collect(Collectors.toList());) on the off chance you were not aware, now that it is confirmed to be an intentional choice (to avoid committing to all vehicles having engines at all or needing to return null if they don't for example), no worries.Re: https://dev.java/learn/api/streams/using-collectors/
In my last comment I reported the "evenNumbers" result containing odds was still showing:
I can confirm that as of the latest, archived at https://web.archive.org/web/20260414161147/https://dev.java/learn/api/streams/using-collectors/ , this has been fixed and it now shows instead:
I will take another set of snapshots and re: review these articles once more today and close this one by EOD if I don't find anything else or any regressions, thanks so much!
JosePaumard commentedon Apr 15, 2026
Thanks to you for your thorough reviews!
willy-b commentedon Apr 16, 2026
No problem!
Found some more small items in this series you may be interested to fix, and at least one previously reported item which fell through the cracks.
In https://dev.java/learn/api/streams/creating/ (archived as is at https://web.archive.org/web/20260415224219/https://dev.java/learn/api/streams/creating/ ):
In the sentence
"gives you a more readable and maintainable code" should be "gives you more readable and maintainable code".
should "due to the limitation of the Playground" be "due to the limitations of" or "due to a limitation of"?
"refactor an existing code" should be "refactor existing code".
Shouldn't this be "the Stream interface extends the AutoCloseable interface" or more precisely,
"the Stream interface extends the BaseStream interface which extends the AutoCloseable interface",
or "Well the good news is that AutoCloseable is a superinterface of Stream".
My understanding is that interfaces are not said to implement other interfaces but rather extend them,
and that is what is happening here:
I think "has also a method for you" might be more clear as "also has a method for you".
In "Here is the code you can write using this method" , it might be clearer as "Here is code you can write using this method" or "Here is an example of code you can write using this method" as it can be applied many different ways
In https://dev.java/learn/api/streams/intermediate-operation/ (archived as is at https://web.archive.org/web/20260416031953/https://dev.java/learn/api/streams/intermediate-operation/ ):
I think "unbound" should be "unbounded" (As in e.g. the sentence describing this property of streams in https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/package-summary.html:
"Possibly unbounded. While collections have a finite size, streams need not. Short-circuiting operations such as limit(n) or findFirst() can allow computations on infinite streams to complete in finite time."
Also, "that will produce" might be clearer as "which would produce".
Finally, it seems "as you can see it on the following example" should be "as you can see in the following example".
The preceding sentence on the processing of the word "three" might also have some minor grammar issues.
In https://dev.java/learn/api/streams/ (archived as is at https://web.archive.org/web/20260415223619/https://dev.java/learn/api/streams/ ):
"all through" should probably be "through all of" (unless "API" is changed to "APIs" in which case "of" can be omitted)
Here are the descriptive sentences without ending periods (3 out of 12, should probably have a period added to be consistent with the others):
In https://dev.java/learn/api/streams/map-filter-reduce/ (archived as is at https://web.archive.org/web/20260415224027/https://dev.java/learn/api/streams/map-filter-reduce/ ):
"your" should be "you".
Thanks so much!
[edited only to fix first archival link which was not formatted properly, one can verify that the link itself and other content did not change in Github]
JosePaumard commentedon Apr 16, 2026
Thank you again for your report! I just pushed a fix.
As for the . at the end of the section titles: I need to make a pass on these so that it's consistent all through the website. Thank you!
willy-b commentedon Apr 17, 2026
Thanks, here are more remaining items in the Streams tutorials (we are converging but not finished).
In the https://dev.java/learn/api/streams/using-collectors/ article (archived as is at https://web.archive.org/web/20260416174816/https://dev.java/learn/api/streams/using-collectors/ ):
[reported earlier but not fixed yet]
In this sentence
"partitionningBy" should be "partitioningBy".
[reported earlier but not completely fixed yet]
In the "Extracting an Ambiguous Maximum Value", the example which you reworked following my earlier question in Typos and possible small errors in the Streams articles ( https://dev.java/learn/api/streams/ ) #200 (comment) , the text for the first part of that example indicates that one of the strings of length 3 is expected to be removed to make the maximum ambiguous:
However, no length 3 string has actually been removed (yet; later code blocks show "one" removed but not here), so while it says the expected output now has 3 lengths tied for 4 strings:
That does not match the actual current output, which still has an unambiguous maximum:
Because the strings have not had a length 3 example removed yet (later it is revealed it is the word "one" which should be removed here):
In the following part of that extended example "Mapping with a Collector" both the actual and expected output include 4 length 3 strings still (the part with output
result = [ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE]), butafter that, in later parts of the example the string "one" is indeed removed so that the output matches the expected and the example demonstrates what is intended.
In the latest version of https://dev.java/learn/api/streams/intermediate-operation/ (archived as is in https://web.archive.org/web/20260416174142/https://dev.java/learn/api/streams/intermediate-operation/ ), where my last comment had reported small errors, most items reported have been fixed but:
I previously reported:
This has been updated by the Oracle team so that "unbound" is now "unbounded", thanks!
But it now says "as you can see on the following example" instead of "as you can see in the following example".
In the latest version of https://dev.java/learn/api/streams/creating/ (archived as is at https://web.archive.org/web/20260416174306/https://dev.java/learn/api/streams/creating/ ), where my last comment had reported small errors, most items reported have been fixed but:
This was attempted to be fixed by your team, who now write
this is almost fixed but it is missing another "which extends" after "BaseStream interface".
In the latest version of https://dev.java/learn/api/streams/terminal-operations/ (archived as is at https://web.archive.org/web/20260416174417/https://dev.java/learn/api/streams/terminal-operations/ )
there is a demonstration of anyMatch which checks if any String in a stream has length exactly three,
but it appears that the result was potentially mistakenly named, as the result variable is named "oneGT3" instead of "oneEQ3" (or similar):
This seems like originally the predicate used for the demo may have been
s -> s.length() > 3instead ofs -> s.length() == 3,but that the predicate was updated without updating the variable name before publishing.
There is one other variable name that might be clearer in this example, which is
allLT10, which suggests all less than 10 ,when it should be less than or equal to 10, orallLTE10:If all Strings have length <= to 10, then none will match the predicate checking that the String has length greater than 10.
In https://dev.java/learn/api/streams/custom-collectors/ (archived as is at https://web.archive.org/web/20260416174904/https://dev.java/learn/api/streams/custom-collectors/ ):
In the examples on this page, only the 3-arg collect method ( https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Stream.html#collect(java.util.function.Supplier,java.util.function.BiConsumer,java.util.function.BiConsumer) ) is shown, not the 1-arg using the Collector interface.
In the context of the Stream 3-arg collect method, as written there is potential for confusion between either the Collector interface or the combiner of a reducer and the 3-arg collect method combiners, between a BinaryOperator (or BiFunction) (used in the Collector interface combiner and reductions, has a return value) and a BiConsumer (used in the 3-arg collect method, has no return value, and updates a container):
The problem with this description of the combiner for the 3-arg collect method combiners shown on this page is that a BiConsumer is NOT a BinaryOperator as Consumers don't return anything (a BiFunction can be a BinaryOperator: a BiFunction with both input types and the output type all the same would be a BinaryOperator of that single type). This is unlike the analogous combiner for a reduce operation which does use a BinaryOperator/BiFunction.
To see where this confusion "BinaryOperator is also modeled by a BiConsumer" (rather than being treated as different functional interfaces used by different collect combiners) probably comes from, compare the 3-argument Stream.collect method signature:
and the Collector interface combiner (as discussed later in https://web.archive.org/web/20260416174917/https://dev.java/learn/api/streams/collector-interface/ ) ( https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collector.html#combiner() )
or the analogous 3-argument reduce method signature:
Note that reduce uses a BinaryOperator for its combiner, but the 3-arg collect method uses a BiConsumer, which is NOT a BinaryOperator.
So e.g. the existing sentence:
is valid for the Collector interface, but in the context of this page https://dev.java/learn/api/streams/custom-collectors/ (archived as is at https://web.archive.org/web/20260416174904/https://dev.java/learn/api/streams/custom-collectors/ ) should mention that for the 3-arg collect
it uses "an instance of BiConsumer" instead of "BinaryOperator", and "that folds the elements from the second result container into the first result container" instead of "takes two partially filled containers and returns one" because the BiConsumer does not (cannot) return anything. See https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Stream.html#collect(java.util.function.Supplier,java.util.function.BiConsumer,java.util.function.BiConsumer) which says "The combiner function must fold the elements from the second result container into the first result container."
Functional interfaces don't need to extend one another to be compatible as long as the signatures are compatible, but a BiConsumer doesn't return anything (operates via side-effects) unlike a BinaryOperator, so the void return and the non-void return are incompatible.
To see this difference between the Collector interface combiner (as discussed later in https://web.archive.org/web/20260416174917/https://dev.java/learn/api/streams/collector-interface/ )
and the Stream 3-arg collect method combiner,
we can look at one of the 3-arg collect examples from this page https://web.archive.org/web/20260416174904/https://dev.java/learn/api/streams/custom-collectors/ (which is about 3-arg collect method usage, on IntStream and String and does not have Collector interface implementations despite the title), and one that uses
Collection::addAllas the combiner which does not return the same type as the mutated collection:The combiner is
BiConsumer<List<Integer>, List<Integer>> combiner = Collection::addAll;,Collection::addAll has the wrong return type to even be used as a BinaryOperator, so it would fail with
So the combiner would have to be changed if the above was written as an implementation of the Collector interface to pass to collect:
So my suggestion is to possibly emphasize that the 1-arg and 3-arg collect methods use different combiner types, without giving the impression that BinaryOperator (working via return type) can be generally substituted wherever one sees BiConsumer (working via side effects) (because it would not work, though some examples like
StringBuffer::appendsuggest that it can as they both mutate the object and return a new reference).In the latest version of https://dev.java/learn/api/streams/reducing/ (archived as is at https://web.archive.org/web/20260416174325/https://dev.java/learn/api/streams/reducing/ )
In the sentence,
"can be summarized on the following figure" should probably be "is summarized in the following figure".
There is a malformed sentence:
Perhaps this was intended to be something like "Here is the code for our custom reduce method along with some code to show it in action".
In the sentence,
"if you cannot find any faulty combination does not mean that your candidate is correct" should probably
be "if you cannot find any faulty combination IT does not [necessarily] mean that your candidate is correct".
In https://dev.java/learn/api/streams/characteristics/ (archived as is in https://web.archive.org/web/20260416174540/https://dev.java/learn/api/streams/characteristics/ ),
In the sentence
"The fist example" should be "The first example".
Re:
This seems incorrect as Maps can have null values associated with its keys (and can have null keys) depending on the Map implementation.
Indeed, in the example below using a HashMap, one observes null values are included in the Collection returned by Map.values() and the associated stream does not have the NONNULL characteristic:
(this is true actually also for the keySet -- and the entrySet -- such that none of the Collections associated with a Map produce a Stream with the NONNULL characteristic at least for some implementations like HashMap meaning it cannot be a guaranteed property)
Thanks!
willy-b commentedon Apr 18, 2026
Note, I edited my last comment to clarify the note I had added on possibly updating https://dev.java/learn/api/streams/custom-collectors/ (archived as is at https://web.archive.org/web/20260416174904/https://dev.java/learn/api/streams/custom-collectors/ )
to emphasize the difference between the 3-arg collect method combiner vs 1-arg collect method combiner (via Collector interface) types. I switched the example I mentioned from the page to the one using the BiConsumer
Collection::addAllas the combiner for the 3-arg collect method as unlike theStringBuffer::appendexample it cannot (in other contexts) be used as a BinaryOperator (StringBuffer:appendmutates theStringBufferAND returns a reference to it so it can be either a BiConsumer or BinaryOperator; whereasCollection::addAllmutates the collection and returns a different type, a boolean, so cannot be a BinaryOperator). I also mentioned that the focus on BinaryOperator would be appropriate for the later page https://web.archive.org/web/20260416174917/https://dev.java/learn/api/streams/collector-interface/ which is on the 1-arg collect method using the Collector interface (unlike the page I commented on). Other parts were not changed. The other items in the comment are clear errors or typos whereas this is a subjective comment on what might be clearer so feel free to focus on the other items and ignore it unless you have time. Thanks.32 remaining items
JosePaumard commentedon Jun 25, 2026
Thank you for your report! A fix is on its way.
authentictech commentedon Jun 25, 2026
I thought I'd put this here rather than opening a new issue. I didn't see this mentioned above.
On https://dev.java/learn/api/streams/gatherers/#interrupt in the Fixing the Distinct Gatherer section:
Should probably be:
Indeed, your integrator is currently being called, so it is bound to be false, and you did not call
downstream.push(), so it could not change.JosePaumard commentedon Jun 25, 2026
Thank you again for your report! A fix is on its way.
willy-b commentedon Jun 27, 2026
Thanks to both of you! Here are a few more items I have uncovered during additional review.
In the latest version of https://dev.java/learn/api/streams/gatherers/ (archived as is at https://web.archive.org/web/20260626201901/https://dev.java/learn/api/streams/gatherers/ )
There are broken links in the sentences
as these link URLs have "Gatherers.html" instead of "Gatherer.html", e.g. there a link to the invalid target https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Gatherers.html#ofSequential(java.util.function.Supplier,java.util.stream.Gatherer.Integrator) when this was clearly intended to be https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Gatherer.html#ofSequential(java.util.function.Supplier,java.util.stream.Gatherer.Integrator) .
In the sentence
"These examples have no other goals than to show you ..., and learn how you can use them" should be "These examples have no other goals than to show you ..., and to help you learn how you can use them."
In the sentence
"it may be useful in your finisher" may have been intended to have a connector, like "but it may be useful in your finisher", or the comma may have been intended as a semicolon, or perhaps a "While" was intended at the beginning of the overall sentence. As it stands there are two standalone sentences connected by a comma which is unusual.
In the sentence
you may wish to double check that "by just calling parallel() on an existing stream" was not intended to be "just by calling parallel() on an existing stream".
In the sentence
you may wish to double check that "that create ... that you can create in your application" was not intended to be "that create ... that you can use in your application" (replacing second "create" in the sentence with "use").
In the sentence
"all the windows produce have" should be "all the windows produced have" ('produce" seems to have been intended to be "produced").
Thanks so much!
JosePaumard commentedon Jun 29, 2026
Thank you again for your report! A fix is on its way.
willy-b commentedon Jul 1, 2026
Thanks for fixing the broken links and other items above.
Here are more items I have found during additional careful review (no AI assistance or LLM is used) of this tutorial series, which you may care to fix.
In the latest version of https://dev.java/learn/api/streams/using-collectors/ (archived as is at https://web.archive.org/web/20260630220135/https://dev.java/learn/api/streams/using-collectors/?no_cache=true )
In the sentence
There are two mistakes:
First, for groupingBy(), the overload linked is again not the one being discussed (the overload linked does not accept a downstream collector): "groupingBy()" is linked to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#groupingBy(java.util.function.Function) which does not accept a downstream collector,
when it should be linked to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#groupingBy(java.util.function.Function,java.util.stream.Collector) .
Second, toMap() should not be mentioned here, as it does not accept a downstream collector in any of its overloads.
Maybe partitioningBy() was intended? Or mapping() , flatMapping(), filtering() , or teeing()?
In the sentences
The wrong type is given for the Map. Even the preceding sentence acknowledges the values of the Map are of type List<NumberOfLength> (" the values are lists of NumberOfLength objects").
Thus the last sentence above should be "The exact type of this map is Map<Long, List<NumberOfLength>>."
In the description under "Post-processing the Values Created with a Grouping By"
the wrong overload of groupingBy is linked in 3 out of 4 cases.
The current links point to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#groupingBy(java.util.function.Function) , when they should, EXCEPT for the case preceded by "In the previous example", instead point to the 2-argument overload which takes a downstream collector, https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#groupingBy(java.util.function.Function,java.util.stream.Collector) .
In the sentence
the groupingBy() overload linked is not the correct one: it links to the 1-argument form https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#groupingBy(java.util.function.Function) when the form referenced (taking a Supplier) is the 3-argument https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#groupingBy(java.util.function.Function,java.util.function.Supplier,java.util.stream.Collector) .
In the sentences
The wrong overload of toMap() is linked. "toMap()" links to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#toMap(java.util.function.Function,java.util.function.Function)
when the overload described is https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#toMap(java.util.function.Function,java.util.function.Function,java.util.function.BinaryOperator) .
In the sentence
the wrong overloads are linked for both methods:
"groupingBy()" links to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#groupingBy(java.util.function.Function)
but the overload taking a Supplier mentioned is https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#groupingBy(java.util.function.Function,java.util.function.Supplier,java.util.stream.Collector) .
"toMap()" links to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#toMap(java.util.function.Function,java.util.function.Function)
but the overload taking a Supplier as mentioned is https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#toMap(java.util.function.Function,java.util.function.Function,java.util.function.BinaryOperator,java.util.function.Supplier) .
In the latest version of https://dev.java/learn/api/streams/creating/ (archived as is https://web.archive.org/web/20260629215321/https://dev.java/learn/api/streams/creating/?no_cache=true ),
In the sentence
the author has linked the wrong overload for the context; "iterate()" links to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Stream.html#iterate(T,java.util.function.UnaryOperator) ,
which is the 2-arg overload when the overload discussed is the 3-arg which takes an additional Predicate.
It should link to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Stream.html#iterate(T,java.util.function.Predicate,java.util.function.UnaryOperator) instead.
In the latest version of https://dev.java/learn/api/streams/reducing/ (archived as is at https://web.archive.org/web/20260629223611/https://dev.java/learn/api/streams/reducing/?no_cache=true )
In the sentence
"All these operations ... consists" should be "All these operations ... consist".
In the sentence
"sum it to" may be clearer than "add it to" for adding just two elements.
"sum it to" is a much rarer phrasing:
In the sentence
"is summarized is the following figure" should be "is summarized in the following figure" (3rd "is" in sentence should be substituted with "in").
In the discussion of the third overload of reduce() , no link to the documentation is provided:
"The third one" is mentioned, as well as "this method", without links, then at the end of this block, when there is a link to "reduce()" it is to a different, simpler overload.
It would be easier for the reader in my opinion if there were a link to this third overload of reduce() so the reader could easily cross-reference the official documentation.
In the latest version of https://dev.java/learn/api/streams/intermediate-operation/ (archived as is at https://web.archive.org/web/20260629211109/https://dev.java/learn/api/streams/intermediate-operation/?no_cache=true ),
In the sentence
"that will produce an unlimited number of objects" should probably be "producing an unlimited number of objects".
In the latest version of https://dev.java/learn/api/streams/terminal-operations/ (archived as is at https://web.archive.org/web/20260630185036/https://dev.java/learn/api/streams/terminal-operations/ ),
In the discussion of anyMatch, allMatch, noneMatch
the behavior for empty streams is not provided, which would be useful for readers as it is perhaps counterintuitive:
For an empty stream, anyMatch returns false, but both allMatch and noneMatch return true for any given Predicate.
(That is to say, the Stream interface JavaDoc says that when the stream is empty,
for any given predicate, allMatch, noneMatch, and anyMatch behave as if
Perhaps these results are not obvious as in other cases allMatch implies anyMatch and either contradicts noneMatch.)
In the latest version of https://dev.java/learn/api/streams/custom-collectors/ (archived as is at https://web.archive.org/web/20260630225938/https://dev.java/learn/api/streams/custom-collectors/?no_cache=true )
In the sentence
(may have been added by the dev.java team recently, as there have been many edits to this part,
I do NOT propose the edits and only look for errors after they have already gone live, NOT involved in review beforehand)
the method linked by "Stream.collect(supplier, combiner, accumulator)"
is
<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R,R> combiner),so the argument labels have been given out of order, it should be supplier, accumulator, then combiner.
In a subsequent sentence, they are already given in the correct order:
In the sentence
"collector" should be "collectors".
In the latest version of https://dev.java/learn/api/streams/optionals/ (archived as is in https://web.archive.org/web/20260701023916/https://dev.java/learn/api/streams/optionals/?no_cache=true )
In the sentence (this is not an error, but something that could potentially confuse some readers, so noting it)
If the release these methods were added in is important, you may consider to clarify this so that nobody misinterprets this to mean that isPresent() was added in Java SE 11 (it was present earlier, e.g. in Java 8 https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#isPresent-- ).
This could be accomplished by modifying the sentence to say "isPresent() which was added in Java SE 8, and isEmpty(), which was added in Java SE 11."
In the sentence (this is not an error, but something that could potentially confuse some readers, so noting it)
while "(A1, A2)" and "(A2, A1)" are clear, the words around them could be clearer.
It may be useful to update just that part to say "a pair of two authors is the same regardless of order: (A1, A2) is the same pair as (A2, A1)".
In the sentence
"This patterns maps" should be "This pattern maps".
In the sentence
the first three methods are methods available on the Optional class that are similar to Stream methods, but the last one "forEach()" is a link to a Stream method.
Presumably, the "equivalent of forEach()" is referring to ifPresent() on Optional as there is no "forEach" on the Optional class.
To avoid confusion, since ifPresent() is not currently mentioned until nearly the end of the page,
it may be useful to replace "and even an equivalent of forEach()"
WITH "and ifPresent() , an equivalent of the Stream method forEach()".
In the latest version of https://dev.java/learn/api/streams/parallel-streams/ (archived as is at https://web.archive.org/web/20260701011932/https://dev.java/learn/api/streams/parallel-streams/?no_cache=true )
In the text and on the sidebar, the heading
"Streams Computations" should be "Stream Computations".
In the sentences
The use of "This is not the case" or "This is the case" here is unclear and seemingly inconsistent.
While the overall meaning is clear enough in the context of this section, I would humbly suggest that it may be despite the writing here rather than because of it.
"This is not the case for all the structures..." refers to the fact that it is not generally true that one can get the number of elements in advance.
But in the very next sentence "This is the case for the Files.lines(path) pattern ... It is not possible to get the number of lines of a text file without analyzing it" , "the case" seems to mean the opposite thing.
I would suggest to get rid of the use of "This is not the case" and "This is the case" and be specific.
E.g. replacing "This is not the case for all the structures from which you can create a stream"
with something like "The number of elements is not available in advance for all the structures from which you can create a stream."
Then also replace "This is the case for the Files.lines(path) pattern ... It is not possible to get the number of lines of a text file without analyzing it",
with something like "For example, in the Files.lines(path) pattern the number of lines are not available in advance ... It is not possible to get the number of lines of a text file without analyzing it."
Thanks!
In the sentence
"overheads" should be "overhead".
In the sentence
"on by one" should be "one by one"
Thanks very much!
JosePaumard commentedon Jul 1, 2026
Thank you again for your report! A fix is on its way.
willy-b commentedon Jul 17, 2026
Thanks so much!
In the latest version of https://dev.java/learn/api/streams/optionals/ (archived as is at https://web.archive.org/web/20260717045756/https://dev.java/learn/api/streams/optionals/?nonce=2 )
In the sentence
"that published to most together" should be "that published the most together" ("to" should be "the").
Nit (optional): In the sentence
it seems "with private constructor" should be "with only a private constructor".
In the latest version of https://dev.java/learn/api/streams/characteristics/ (archived as is at https://web.archive.org/web/20260717011211/https://dev.java/learn/api/streams/characteristics/?nonce=2 ) ,
In the sentence
" There are structures from the Collection Framework that do not accept null values,"
"Collection Framework" should be "Collections Framework".
In the latest version of https://dev.java/learn/api/streams/using-collectors/ (archived as is at https://web.archive.org/web/20260716093742/https://dev.java/learn/api/streams/using-collectors/?nonce=1 ) ,
In the sentences
"toMap()" still links to the wrong overload, as it links to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#toMap(java.util.function.Function,java.util.function.Function)
when it should link to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Collectors.html#toMap(java.util.function.Function,java.util.function.Function,java.util.function.BinaryOperator) .
In the latest version of https://dev.java/learn/api/streams/creating/ (archived as is at https://web.archive.org/web/20260716092501/https://dev.java/learn/api/streams/creating/?nonce=1 )
In the sentence
the author has linked the wrong overload for the context; "iterate()" links to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Stream.html#iterate(T,java.util.function.UnaryOperator) ,
which is the 2-arg overload when the overload discussed is the 3-arg which takes an additional Predicate, so it should link to https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/stream/Stream.html#iterate(T,java.util.function.Predicate,java.util.function.UnaryOperator) .
In the latest versions of https://dev.java/learn/api/streams/terminal-operations/ (archived as is at https://web.archive.org/web/20260716094428/https://dev.java/learn/api/streams/terminal-operations/ )
Thanks for adding the description of the behavior for empty streams for
anyMatch,allMatch,noneMatch:As far as the change to show the empty stream behavior in the subsequent code example, I have a thought you may care to respond to or ignore per your preference. Though technically sufficient, the new demonstrations of anyMatch, allMatch, noneMatch on empty streams use different predicates; while the predicate is irrelevant on the empty streams the changing predicate may miss making it clear that for the same predicate allMatch and noneMatch will both be simultaneously true for empty streams, and anyMatch will be false (which is counterintuitive). But with the addition of the information on empty stream behavior to the anyMatch/allMatch/noneMatch introductions the original concern is solved.
Thanks!
JosePaumard commentedon Jul 18, 2026
Thank you again for your report! A fix is on its way.
willy-b commentedon Jul 20, 2026
Thanks for the excellent updates to the empty stream examples for the anyMatch, allMatch, noneMatch stream operations! Those are well covered now.
Here are a few remaining other items I found in the latest versions of these Stream tutorial pages.
In the latest version of https://dev.java/learn/api/streams/gatherers/ (archived as is at https://web.archive.org/web/20260720003101/https://dev.java/learn/api/streams/gatherers/?no_cache=true )
In the sentences
the combiner is NOT the fourth parameter but rather the third (it is true that given also the initializer, integrator, and finisher there are four total) so "you need to provide a fourth parameter, called a combiner" is not accurate. Maybe it could be reworded as "you need to provide a combiner as the third parameter, leading to a total of four parameters" or something.
In the sentence
I think "our good old friend the NullPointerException" was intended instead of "our old friend the good NullPointerException" (NPEs are not good and the phrase is "good old friend")
In the latest version of https://dev.java/learn/api/streams/parallel-streams/ (archived as is at https://web.archive.org/web/20260719194140/https://dev.java/learn/api/streams/parallel-streams/?nonce=1 ),
In the sentence
"the performances of ... have indeed improved" should be "the performance of ... has indeed improved".
In the sentence
"hit the performance of" is an unusual phrasing (though one often hears of "taking a performance hit due to "). I would humbly suggest to rephrase this to "negatively impact the performance of".
In the latest version of https://dev.java/learn/api/streams/optionals/ (archived as is at https://web.archive.org/web/20260719122505/https://dev.java/learn/api/streams/optionals/?nonce=11 )
In the sentence
"which an equivalent of" is not grammatical. It could be replaced with "which is analogous to Stream.forEach()", as one suggestion.
Thanks so much!
JosePaumard commentedon Jul 20, 2026
Thank you again for your report! A fix is on its way.
willy-b commentedon Jul 21, 2026
Can you confirm the changes were deployed? I don't see the updates yet, thanks!
JosePaumard commentedon Jul 24, 2026
Sorry for the delay. It should be live in a few mn now.
willy-b commentedon Jul 25, 2026
Thanks, almost all items reported above were resolved.
The update made to the latest version of https://dev.java/learn/api/streams/optionals/ (archived as is at https://web.archive.org/web/20260724224757/https://dev.java/learn/api/streams/optionals/?nonce=1 ) is not quite complete:
In the sentence
the "of" in "analogous to of" should still be removed.
Thanks!
willy-b commentedon Aug 11, 2026
Thanks for fixing the item mentioned in my last comment!
In the latest version of https://dev.java/learn/api/streams/map-filter-reduce/ (archived as is at https://megalodon.jp/2026-0812-0021-17/https://dev.java:443/learn/api/streams/map-filter-reduce/ as web.archive.org is not storing snapshots for me today )
In the sentence
"another map-filter-reduce processing on a list of cities" might be clearer as "another map-filter-reduce processing of a list of cities" or some other phrasing.
In the following lines from a code example on that page (note in megalodon snapshot one may need to check the HTML as the code snippets do not display)
It may be clearer to write "no map() on the List (nor Collection) interface" as the variable in question is an instance of List (which extends Collection), not Collection.
In the latest version of https://dev.java/learn/api/streams/intermediate-operation/ (archived as is at https://megalodon.jp/2026-0812-0023-22/https://dev.java:443/learn/api/streams/intermediate-operation/ ),
In the line of code (occurring identically in two of the examples), (note in megalodon snapshot one may need to check the HTML as the code snippets do not display)
it appears that it is unintentionally the case that "newYork=" is missing a space between "newYork" and "=" (doesn't break anything, not a blocker) (not the case for any of the other cities listed)
In the following sentences referring to Stream.mapMulti:
Re
Nothing about using mapMulti in a static vs non-static context is to my knowledge mentioned in the API documentation for mapMulti (https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/stream/Stream.html#mapMulti(java.util.function.BiConsumer). mapMulti is a non-static instance method, so I wonder if this statement is in error or could perhaps be clarified (I am probably not the only person who finds it confusing). It occurs in part of the text that has been added recently by the dev.java team to explain what is explained in the API documentation as:
which does not mention static contexts. The rest of the explanation is in my opinion clear.
In the sentence
"needs to see all the elements produced before producing them" would probably be clearer as "needs to see all the elements produced before processing them" (with "before producing them" replaced with "before processing them", or maybe with "before forwarding the sorted version of the input elements").
In the latest version of https://dev.java/learn/api/streams/creating/ (archived as is at https://web.archive.org/web/20260811013427/https://dev.java/learn/api/streams/creating/?nonce=32 )
In the list item
"with a regular expressions" should be "with a regular expression".
On https://dev.java/learn/api/streams/optionals/ (archived as is at https://megalodon.jp/2026-0812-0015-56/https://dev.java:443/learn/api/streams/optionals/?nonce=30 ) http://web.archive.org is refusing to archive it today)
In the sentence
it seems that "does in fact this" should probably be "in fact does this"
e.g. compare https://books.google.com/ngrams/graph?content=does+in+fact+this%2C+in+fact+does+this&year_start=1800&year_end=2022&corpus=en&smoothing=3
Thanks!