Unexpected behavior of the toString method in Java

I’m trying to implement the append method in a my DoublyLinkedList class and I’m getting some error related to the toString method

public class DoublyLinkedList {
    private Node head;
    private Node tail;
    private int length;
    static class Node {
        int value;
        Node prev;
        Node next;

        public Node(int value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "value=" + value +
                    ", prev=" + prev +
                    ", next=" + next +
                    '}';
        }
    }

    public DoublyLinkedList(int value) {
        this.head = new Node(value);
        this.tail = this.head;
        this.length = 1;
    }

    public void append(int value) {
        Node newNode = new Node(value);
        if (this.length == 0) {
            this.head = newNode;
            this.tail = newNode;
            return;
        }
        this.tail.next = newNode;
        newNode.prev = this.tail;
        this.tail = newNode;
        this.length++;
    }

    @Override
    public String toString() {
        return "DoublyLinkedList{\n" +
                "\thead=" + head +
                ",\n\ttail=" + tail +
                ",\n\tlength=" + length +
                "\n}";
    }
}
public class Main {
    public static void main(String[] args) {
        DoublyLinkedList doublyLinkedList = new DoublyLinkedList(1);
        doublyLinkedList.append(2);
        System.out.println(doublyLinkedList);
    }
}

I’m getting like tons of these error messages in my standard output

tech.othmane.doublylinkedlist.Main
Exception in thread "main" java.lang.StackOverflowError
    at tech.othmane.doublylinkedlist.DoublyLinkedList$Node.toString(DoublyLinkedList.java:18)
    at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)
    at tech.othmane.doublylinkedlist.DoublyLinkedList$Node.toString(DoublyLinkedList.java:18)
    at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)
    at tech.othmane.doublylinkedlist.DoublyLinkedList$Node.toString(DoublyLinkedList.java:18)
    at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)
    at tech.othmane.doublylinkedlist.DoublyLinkedList$Node.toString(DoublyLinkedList.java:18)
    at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)
    at tech.othmane.doublylinkedlist.DoublyLinkedList$Node.toString(DoublyLinkedList.java:18)
    at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)
    at tech.othmane.doublylinkedlist.DoublyLinkedList$Node.toString(DoublyLinkedList.java:18)
    at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)

The issue is related to the toString method in the Node class.

@Override
        public String toString() {
            return "Node{" +
                    "value=" + value +
                    ", prev=" + prev +
                    ", next=" + next +
                    '}';
        }

When I comment out either the prev or the next field, the code works

>Solution :

You are getting a StackOverflowError. This is because in the Node class toString(), you are invoking the Node#toString on both prev and next. This will cause an infinite recursive toString calls.

Let’s say you have a two node list like, 1 -> 2.

  • Node 1 will call next of 2 and
  • Node 2 will call prev of 1 and
  • Node 1 will call next of 2 and
  • so on (endless cycle)

A Node class toString should just return the value of the node.

@Override
public String toString() {
     return "Node{value = " + value + "}";
}

You can take care of iterating over the nodes in the DoublyLinkedList class to build the toString showing all elements.

Leave a Reply