Skip to content

Typos and small errors in "The Collections Framework" tutorials ( https://dev.java/learn/api/collections-framework/ ) #206

@willy-b

Description

@willy-b

Hello dev.java team!

Thanks so much for all this excellent content.
Just reporting some typos, some possibly outdated content, and some small errors (primarily in the "Storing Elements in Stacks and Queues" article, reported at the bottom of this issue comment).


In "Iterating over the Elements of a Collection", https://dev.java/learn/api/collections-framework/iterating/ , (archived as is at https://web.archive.org/web/20260305204909/https://dev.java/learn/api/collections-framework/iterating/ ),

The Iterable/Iterator implementations (both the record and "plain class" approaches presented) appear to have possible small issues

Image
  • the limit of the hasNext() is not consistent with the next() (when hasNext() returns false, there is still another element to be returned by next(), see below)
  • where one could simply write return index++; to get-and-increment, an unnecessary secondary variable is used
record Range(int start, int end) implements Iterable<Integer> {

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<>() {
            private int index = start;
            
            @Override
            public boolean hasNext() {
                return index < end; // hasNext() uses a half-open end excluded interval
            }

           @Override
            public Integer next() {
                if (index > end) { // next() uses a closed end included interval, should be >= to be consistent; next() can go one further after hasNext() returns false here
                    throw new NoSuchElementException("" + index);
                }
                int currentIndex = index;
                index++;
                return currentIndex; // maybe could just `return index++;` for desired get-and-increment behavior
            }

The inconsistency of where next() stops returning elements and how hasNext() is defined can be demonstrated as follows:

jshell> Range r = new Range(0, 3);
r ==> Range[start=0, end=3]

jshell> var rIter = r.iterator();
rIter ==> Range$1@ff5b51f

jshell> rIter.next();
$4 ==> 0

jshell> rIter.next();
$5 ==> 1

jshell> rIter.next();
$6 ==> 2

jshell> // here the hasNext will start saying false, since they wrote hasNext in a half-open end excluded limi
t

jshell> rIter.hasNext();
$7 ==> false

jshell> // but the next() method supports up to including the limit, so it does have a next element

jshell> rIter.next();
$8 ==> 3

jshell> rIter.hasNext(); // still false
$9 ==> false

jshell> rIter.next(); // now will fail
|  Exception java.util.NoSuchElementException: 4
|        at Range$1.next (#1:16)
|        at Range$1.next (#1:5)
|        at (#10:1)


If you compare that to the default List iterator implementations, that is not the behavior (hasNext() usually returns false only if the next call to next() will throw NoSuchElementException).

The same issues also occur in the "plain class" example that follows.

  • Separately, there appears to be a typo on the line:
for (int i : new Range1(0, 5)) {

in that "Range1" is written when "Range" seems intended.


In the Table of Contents for this tutorial, https://dev.java/learn/api/collections-framework/ (archived as is: https://web.archive.org/web/20260305180836/https://dev.java/learn/api/collections-framework/ ):

  • "Why Choosing a Collection over an Array?" should be "Why Choose a Collection over an Array?"
  • "Using a Collection to Store and Retrieve Elements" is missing a period at the end

In "Storing Data Using the Collections Framework", https://dev.java/learn/api/collections-framework/intro/ (archived as is at: https://web.archive.org/web/20260305183418/https://dev.java/learn/api/collections-framework/intro/ ):

  • The sentence "Is what you need consists in:", I think a different sentence is intended, beginning with "If" instead of "Is"

In "Getting to Know the Collection Hierarchy", https://dev.java/learn/api/collections-framework/organization/
(archived as is https://web.archive.org/web/20260305191553/https://dev.java/learn/api/collections-framework/organization/ ):


In "Storing Elements in a Collection", https://dev.java/learn/api/collections-framework/collection-interface/ (archived as is: https://web.archive.org/web/20260305200446/https://dev.java/learn/api/collections-framework/collection-interface/ ):

  • In the sentence, "You will see more discussions on the right implementation to choose in later in this tutorial",
    "to choose in later in this tutorial" should be "to choose later in this tutorial" (remove extra "in").

In "Creating and Processing Data with the Collections Factory Methods", https://dev.java/learn/api/collections-framework/immutable-collections/ (archived as is at https://web.archive.org/web/20260305231534/https://dev.java/learn/api/collections-framework/immutable-collections/ ):


In "Storing Elements in Stacks and Queues", https://dev.java/learn/api/collections-framework/stacks-queues/ (archived as is at https://web.archive.org/web/20260305234616/https://dev.java/learn/api/collections-framework/stacks-queues/ ):

Image
  • re: the text block on Deque methods:

Moreover, Deque also defines the methods you would expect in any queue or stack class:

push(element): adds the given element to the head of the double ended queue
pop(): removes and return the element at the head of the double ended queue
poll(): does the same at the tail of the double ended queue
peek(): shows you the element at the tail of the double ended queue.

The sentences on Deque poll and peek behavior appear incorrect,
e.g., "poll(): does the same at the tail of the double ended queue", appears to be mistaken in that poll removes from the head, not the tail as written.

Image

Compare this to the official documentation, https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/Deque.html#poll()
which says

Retrieves and removes the head of the queue represented by this deque (in other words, the first element of this deque), or returns null if this deque is empty.
This method is equivalent to pollFirst().

The same error occurs for peek, as peek also shows the element at the head, not the tail of the Deque (see https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/Deque.html#peek() ).

  • The sentence "In case there is no element to pop, poll, or peek, then a null value is returned by these methods."
    appears mistaken as pop throws NoSuchElementException when the Deque is empty (see https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/Deque.html#pop() ).

  • The sentence "There is one difference though: the peek operations are named getFirst() and getLast() in Deque, and element() in Queue."
    seems confusing as "peek" is available in Deque and Queue (as well as the equivalent peekFirst() and also a peekLast()), whereas this sentence suggests they are not.
    There are also the mentioned getFirst()/getLast() in Deque and element() in Queue that also return elements without removing them but which throw NoSuchElementException instead of returning null on empty Deques or Queues.

Finally, this may not be an error, but I think is worth reviewing:
Near the beginning of this article, it is written of stacks and queues that:

These structures are very simple and gives you three main operations.
push(element): adds an element to the queue, or the stack
pop(): removes an element from the stack, that is, the youngest element added
poll(): removes an element from the queue, that is, the oldest element added
peek(): allows you to see the element you will get with a pop() or a poll(), but without removing it from the queue of the stack.

In this explanation, the sentence "push(element): adds an element to the queue, or the stack" might be confusing as the Queue interface actually only includes "add" and "offer" for adding to the queue , NOT push, which comes from the stack interface ( see https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/Queue.html ).

From Java 25 SE documentation, Queues have:

Summary of Queue methods
Throws exception Returns special value
Insert add(e) offer(e)
Remove remove() poll()
Examine element() peek()

and Stacks have push, pop, and peek ( https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/Stack.html ).
The article does discuss this later, defining push operations for a queue as add and offer, but I think "push(element)" in reference to a queue might be better immediately paired with a clarifying statement that "add" or "offer" are the actual method names, not "push" for a queue.


Depending on available time I may add additional items here as I am still reviewing this series of artices so feel free to leave open even if you address the above (I would also be happy to confirm any changes before closing if desired).

Thanks very much!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions