1) SortedLinkedList extends BasicLinkedList but both have

private Node head; 
private Node tail

this is wrong. If you want to inherit those field in the sub class, you should mark the variables as protected in the super class and remove them from the subclass.

2) Same goes for private class Node. You are declaring the Node class in both the SortedLinkedList and BasicLinkedList. What you should do is declare it once, (maybe in the super class?) and use the same class in both places. If you do this, the constructor, and the fields should be accessible to both classes. So you will have to change the access modifier (private is what you have now).

I will post below code that works, but I haven't spent any time on the design. Just posting it to demonstrate how you could change the code to make it work. You will have to decide which access modifiers to use and where to put the classes.

import java.util.Comparator;
import java.util.Iterator;

public class Test {
    public static void main(String[] args) {
        System.out.println("---------------SortedLinkedList--------------");
        SortedLinkedList<Integer> sortedList = new SortedLinkedList<Integer>(new intComparator());
        sortedList.add(3);
        sortedList.add(5);
        sortedList.add(2);
        for (int i : sortedList) {
            System.out.println(i);
        }
    }
}

class BasicLinkedList<T> implements Iterable<T> {
    public int size;

    class Node {
        T data;
        Node next;

        Node(T data) {
            this.data = data;
            next = null;
        }
    }

    protected Node head;
    protected Node tail;

    public BasicLinkedList() {
        head = tail = null;
    }

    // Add, remove method

    public Iterator<T> iterator() {
        return new Iterator<T>() {

            Node current = head;

            @Override
            public boolean hasNext() {
                return current != null;
            }

            @Override
            public T next() {
                if (hasNext()) {
                    T data = current.data;
                    current = current.next;
                    return data;
                }
                return null;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("Remove not implemented.");
            }

        };

    }
}

class SortedLinkedList<T> extends BasicLinkedList<T> {


    private Comparator<T> comp;

    public SortedLinkedList(Comparator<T> comparator) {
        super();
        this.comp = comparator;
    }

    public SortedLinkedList<T> add(T element) {
        Node n = new Node(element);
        Node prev = null, curr = head;
        if (head == null) {
            head = n;
            tail = n;
        }
        // See if the element goes at the very front
        else if (comp.compare(n.data, curr.data) <= 0) {
            n.next = head;
            head = n;
        }
        // See if the element is to be inserted at the very end
        else if (comp.compare(n.data, tail.data) >= 0) {
            tail.next = n;
            tail = n;
        }
        // If element is to be inserted in the middle
        else {
            while (comp.compare(n.data, curr.data) > 0) {
                prev = curr;
                curr = curr.next;
            }
            prev.next = n;
            n.next = curr;
        }

        size++;
        return this;
    }
}

class intComparator implements Comparator<Integer> {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o1 - o2;
    }
}
Answer from Can't Tell on Stack Overflow
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › LinkedList.html
LinkedList (Java Platform SE 8 )
July 21, 2026 - a ListIterator of the elements in this list (in proper sequence), starting at the specified position in the list ... Returns an iterator over the elements in this deque in reverse sequential order. The elements will be returned in order from last (tail) to first (head).
🌐
W3Schools
w3schools.com › java › ref_linkedlist_iterator.asp
Java LinkedList iterator() Method
add() addAll() clear() clone() contains ensureCapacity() forEach() get() indexOf() isEmpty() iterator() lastIndexOf() listIterator() remove() removeAll() removeIf() replaceAll() retainAll() set() size() sort() spliterator() subList() toArray() trimToSize() Java LinkedList Methods
Top answer
1 of 1
3

1) SortedLinkedList extends BasicLinkedList but both have

private Node head; 
private Node tail

this is wrong. If you want to inherit those field in the sub class, you should mark the variables as protected in the super class and remove them from the subclass.

2) Same goes for private class Node. You are declaring the Node class in both the SortedLinkedList and BasicLinkedList. What you should do is declare it once, (maybe in the super class?) and use the same class in both places. If you do this, the constructor, and the fields should be accessible to both classes. So you will have to change the access modifier (private is what you have now).

I will post below code that works, but I haven't spent any time on the design. Just posting it to demonstrate how you could change the code to make it work. You will have to decide which access modifiers to use and where to put the classes.

import java.util.Comparator;
import java.util.Iterator;

public class Test {
    public static void main(String[] args) {
        System.out.println("---------------SortedLinkedList--------------");
        SortedLinkedList<Integer> sortedList = new SortedLinkedList<Integer>(new intComparator());
        sortedList.add(3);
        sortedList.add(5);
        sortedList.add(2);
        for (int i : sortedList) {
            System.out.println(i);
        }
    }
}

class BasicLinkedList<T> implements Iterable<T> {
    public int size;

    class Node {
        T data;
        Node next;

        Node(T data) {
            this.data = data;
            next = null;
        }
    }

    protected Node head;
    protected Node tail;

    public BasicLinkedList() {
        head = tail = null;
    }

    // Add, remove method

    public Iterator<T> iterator() {
        return new Iterator<T>() {

            Node current = head;

            @Override
            public boolean hasNext() {
                return current != null;
            }

            @Override
            public T next() {
                if (hasNext()) {
                    T data = current.data;
                    current = current.next;
                    return data;
                }
                return null;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("Remove not implemented.");
            }

        };

    }
}

class SortedLinkedList<T> extends BasicLinkedList<T> {


    private Comparator<T> comp;

    public SortedLinkedList(Comparator<T> comparator) {
        super();
        this.comp = comparator;
    }

    public SortedLinkedList<T> add(T element) {
        Node n = new Node(element);
        Node prev = null, curr = head;
        if (head == null) {
            head = n;
            tail = n;
        }
        // See if the element goes at the very front
        else if (comp.compare(n.data, curr.data) <= 0) {
            n.next = head;
            head = n;
        }
        // See if the element is to be inserted at the very end
        else if (comp.compare(n.data, tail.data) >= 0) {
            tail.next = n;
            tail = n;
        }
        // If element is to be inserted in the middle
        else {
            while (comp.compare(n.data, curr.data) > 0) {
                prev = curr;
                curr = curr.next;
            }
            prev.next = n;
            n.next = curr;
        }

        size++;
        return this;
    }
}

class intComparator implements Comparator<Integer> {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o1 - o2;
    }
}
🌐
GeeksforGeeks
geeksforgeeks.org › java › how-to-iterate-linkedlist-in-java
How to Iterate LinkedList in Java? - GeeksforGeeks
July 23, 2025 - To iterate the LinkedList using the iterator we first create an iterator to the current list and keep on printing the next element using the next() method until the next element exists inside the LinkedList.
🌐
GeeksforGeeks
geeksforgeeks.org › java › linkedlist-listiterator-method-in-java
LinkedList listIterator() Method in Java - GeeksforGeeks
July 11, 2025 - In Java, the listIterator() method of the LinkedList class returns a ListIterator that allows us to iterate over the elements of the list.
🌐
Crunchify
crunchify.com › java j2ee tutorials › how to iterate through linkedlist instance in java?
How to Iterate through LinkedList Instance in Java? • Crunchify
February 9, 2023 - A linked list is a data structure ... to the next node. In Java, the LinkedList class implements the Iterable interface, which provides several ways to iterate through its elements....
🌐
TutorialsPoint
tutorialspoint.com › java › util › linkedlist_listiterator.htm
Java LinkedList listIterator() Method
... The Java LinkedList listIterator(index) method returns an list iterator over the elements in this list, starting at specified point. The specified index indicates the first element to be returned by an initial call to next.
🌐
TutorialsPoint
tutorialspoint.com › article › iterate-through-a-linkedlist-using-an-iterator-in-java
Iterate through a LinkedList using an Iterator in Java
June 29, 2020 - An Iterator can be used to loop through an LinkedList. The method hasNext( ) returns true if there are more elements in LinkedList and false otherwise. The method next( ) returns the next element in the LinkedList and throws the exception ...
Find elsewhere
🌐
BeginnersBook
beginnersbook.com › 2014 › 07 › java-linkedlist-iterator-example
Java – LinkedList Iterator example
September 11, 2022 - 1) Create a LinkedList 2) Add element to it using add(Element E) method 3) Obtain the iterator by calling iterator() method 4) Traverse the list using hasNext() and next() method of Iterator class. import java.util.LinkedList; import java.util.Iterator; public class IteratorExample { public ...
🌐
Temple University
cis.temple.edu › ~giorgio › cis67 › BigJava2Slides › slides20
Horstmann Chapter 19
The next method should only be called when the iterator is not at the end of the list ... private class LinkedListIterator implements ListIterator { . . . public boolean hasNext() { if (position == null) return first != null; else return position.next != null; } .
🌐
Delft Stack
delftstack.com › home › howto › java › java iterate through a linked list
How to Iterate Through a Linked List in Java | Delft Stack
February 2, 2024 - After the creation of the list, we use the for loop for iteration over it. In the below code, int i=0 is an instantiation of the counter variable. Use a condition indicating the variable should be less than the size of the list.
🌐
University of Hawaii
www2.hawaii.edu › ~esb › 2011spring.ics211 › feb03.html
doubly-linked lists
The sieve of Eratosthenes is relatively simple using Linked Lists and iterators: private static java.util.LinkedList<Integer> filter(java.util.LinkedList<Integer> list) { java.util.LinkedList<Integer> result = new java.util.LinkedList<Integer>();
Top answer
1 of 2
7

Does the code comply with the Java coding conventions?

I think it does comply quite well. A tiny thing is that it would be better to put a space between ){, for example in if (list.isEmpty()){. More importantly, it can be simplified.


There is no need for the inner list variable pointing to this. The inner (non-static) class has direct access to the containing class' fields and methods: it can access firstNode directly from the containing list. So in this code:

final MyLinkedList<T> list = this;
return new Iterator<T>() {
    final Node<T> firstNode = list.firstNode;

You can drop both the list variable and the firstNode variable.


It's a minor thing, but currentNode can be private.


The hasNext method can be simplified by a lot:

@Override
public boolean hasNext() {
    if (list.isEmpty()) {
        return false;
    } else if (currentNode == null){
        return true;
    } else if (currentNode == list.lastNode){
        return false;
    }
    return true;
}

This is equivalent:

@Override
public boolean hasNext() {
    return !isEmpty() && currentNode != lastNode;
}

Could this be made significantly faster?

Slightly. Notice that the isEmpty() check is pointless to perform for every iteration of a non-empty list. So as a minor optimization, you could check for emptiness once, in the beginning, and then omit all the isEmpty() checks from the rest of the code.

Suggested implementation

Putting it all together:

public Iterator<T> iterator() {
    if (isEmpty()) {
        return Collections.<T>emptyList().iterator();
    }
    return new Iterator<T>() {
        private Node<T> currentNode = null;

        @Override
        public boolean hasNext() {
            return currentNode != lastNode;
        }

        @Override
        public T next() {
            if (currentNode == null) {
                currentNode = firstNode;
                return currentNode.data;
            }
            if (currentNode.nextNode == null) {
                throw new NoSuchElementException();
            }
            currentNode = currentNode.nextNode;
            return currentNode.data;
        }
    };
}

Unit testing

I didn't just refactor aggressively. I wrote unit tests first to know that I'm not breaking anything. After that I could go ahead and refactor aggressively:

@Test
public void testEmpty() {
    MyLinkedList<Integer> list = new MyLinkedList<>();
    assertFalse(list.iterator().hasNext());
}

@Test(expected = NoSuchElementException.class)
public void throwIfNextOnEmpty() {
    MyLinkedList<Integer> list = new MyLinkedList<>();
    list.iterator().next();
}

@Test(expected = NoSuchElementException.class)
public void throwIfIterateBeyond() {
    MyLinkedList<Integer> list = new MyLinkedList<>();
    list.add(1);
    list.add(2);
    Iterator<Integer> iter = list.iterator();
    iter.next();
    iter.next();
    iter.next();
}

@Test
public void testStandardIteration() {
    MyLinkedList<Integer> list = new MyLinkedList<>();
    Integer[] items = { 12, 3, 4 };
    for (int i : items) {
        list.add(i);
    }
    Iterator<Integer> iter = list.iterator();
    for (Integer item : items) {
        assertTrue(iter.hasNext());
        assertEquals(item, iter.next());
    }
    assertFalse(iter.hasNext());
}

These may not be perfect, and might not cover all corner cases, but I hope they are enough to get you started.

2 of 2
7

There's a trick with Iterator implementations that can make the logic much simpler, if you caan get your head around the slightly back-to-front implementation.

In your code, you have implemented a system where it checks the state of the list before iterating, but, if you think of an iterator as being a cycle of:

  1. check if there's another member
  2. advance to the next member
  3. return the member
  4. go to 1.

then, what you are doing, is having your 'mindset' anchored at the spot just before step 1. Step 1 is what you consider to be the 'base' state of the cycle.

But, there's no reason for that, you can actually anchor the cycle at the spot just in between step 2 and step 3.

The way this works, is easier to explain with code, rather than words....

... as an aside, there's no need to have the final MyLinkedList list = this because you can reference MyLinkedList.this.firstNode, etc.

public Iterator<T> iterator() {

    return new Iterator<T>() {

        private Node<T> followingNode = firstNode;

        @Override
        public boolean hasNext() {
            return followingNode != null;
        }

        @Override
        public T next() {
            if (followingNode == null) {
                throw new NoSuchElementException();
            }
            T toReturn = followingNode.data;
            followingNode = followingNode.nextNode;
            return toReturn;
        }
    };
}

Notice how the 'state' of the iterator is 'ready' to return the next() value. Because the iterator is set up that way, the check to see hasNext() is really easy... all you have to do is see if the current state is valid. Also, in the next() method the state check is also very easy, and we harvest the return value from the known-valid state, and then we advance to the next state before returning the value. We don't need to check if the next state is valid because that will happen on the next-go-around.

While I was putting that together, I noticed some other things too. In your code you have:

        if (list.isEmpty()){
            throw new NoSuchElementException();
        } else if (currentNode == null){
            this.currentNode = firstNode;
            return currentNode.data;
        } else if (currentNode.nextNode == null) {
            throw new NoSuchElementException();
        }

Those else-if blocks are not necessary. Each block exits the function (either through a throw or a return. You should write blocks like that as:

        if (list.isEmpty()){
            throw new NoSuchElementException();
        }
        if (currentNode == null){
            this.currentNode = firstNode;
            return currentNode.data;
        }
        if (currentNode.nextNode == null) {
            throw new NoSuchElementException();
        }
🌐
Coderanch
coderanch.com › t › 622233 › java › Creating-iterator-linkedlist
Creating an iterator for a linkedlist (Beginning Java forum at Coderanch)
Let us say you have a LinkedList containing three nodes, a, b, and c. Now you want to remove the node b using an iterator. As per your remove logic, you would nullify b. But does it change what a's next is pointing to? Further if it is the a node you wanted to remove, shouldn't the reference of first be updated? How about you write down the intended logic of your removemethod in plain english first and then turn it into Java ...
🌐
Oracle
docs.oracle.com › javase › 7 › docs › api › java › util › LinkedList.html
LinkedList (Java Platform SE 7 )
a ListIterator of the elements in this list (in proper sequence), starting at the specified position in the list ... Returns an iterator over the elements in this deque in reverse sequential order. The elements will be returned in order from last (tail) to first (head).
🌐
Ryerson
cs.ryerson.ca › cps109 › CLASSES › week11 › Ch15 › ch15.html
Horstmann Chapter 15
The next method should only be called when the iterator is not at the end of the list ... private class LinkedListIterator implements ListIterator { . . . public boolean hasNext() { if (position == null) return first != null; else return position.next != null; } .
🌐
Oberlin
cs.oberlin.edu › ~cs151 › lab-4 › l-part-4 › index.html
Doubly Linked List Iterator - CSCI 151: Data Structures
June 13, 2021 - In this part of the lab, we will create a ListIterator called MyLinkedListIterator for our MyLinkedList class that will allow us to iterate through our data structure without accessing any item by its index, similar to how we looped in Part 3 of the Warmup. Given the way a linked list is organized, this type of access is faster than using the get method whenever we want to loop over successive items in the list.
🌐
DigitalOcean
digitalocean.com › community › tutorials › java-listiterator
Java ListIterator - ListIterator in Java | DigitalOcean
August 4, 2022 - As ListIterator’s Cursor points to the before the first element of the LinkedList, hasPrevious() method returns a false value. After observing all these diagrams, we can say that Java ListIterator supports Both Forward Direction and Backward Direction Iterations as shown in the below diagrams.