简体   繁体   中英

Adding an element to a singly linked list in Java

I'm implementing a singly linked list in Java. What I don't like about this code is that I need to check if (head.next == null) every time I add an element. But the condition is met only once, when adding the first element.

Is there a way to implement a singly linked non-circular list without such a condition?

package sample;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class SinglyLinkedList<T> implements Iterable<T> {

    private Node<T> head = new Node<T>(null);
    private Node<T> last = null;

    public SinglyLinkedList(T... elements) {
        addAll(elements);
    }

    public void add(T element) {
        if (head.next == null) {
            head.next = new Node<T>(element);
            last = head.next;
        } else {
            Node<T> newNode = new Node<T>(element);
            last.next = newNode;
            last = last.next;
        }
    }

    public void addAll(T... elements) {
        for (T element : elements) {
            add(element);
        }
    }

    @Override
    public String toString() {
        Iterator<T> iterator = iterator();
        if (!iterator.hasNext()) {
            return "[]";
        }
        StringBuilder builder = new StringBuilder();
        builder.append("[");
        while (iterator.hasNext()) {
            T element = iterator.next();
            builder.append(element);
            if (!iterator.hasNext()) {
                return builder.append("]").toString();
            }
            builder.append(", ");
        }
        return builder.toString();
    }

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

            Node<T> current = head;

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

            @Override
            public T next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                Node<T> temp = current;
                current = current.next;
                return temp.next.element;
            }

        };
    }

    private static class Node<T> {

        private Node<T> next;
        private T element;

        Node(T element) {
            this.element = element;
        }

        @Override
        public String toString() {
            return element.toString();
        }
    }
}

There are many cases where "good OO design" allows you to go without if/else checks; most often by using some form of polymorphism.

Meaning: instead of asking some object about some property, to then make a decision on that in your client code, you somehow make sure that your client code can simply call a method on some other object. And then, the "if" is "hidden" within the code that initially generated that "other object" and gave it to your client code. (you find some nice examples how that works in these videos ).

But - I think this would be clear overkill in this case!

The point is: from a readability point of view, that one check really doesn't hurt (you could refactor things into more methods maybe). And performance ... doesn't matter either. If your code is called so often that it would matter, the JIT will kick in anyway, and probably create code that that takes the correct branch directly for most cases.

Thus: this is a nice implementation; and I think you shouldn't worry about this one if-check there!

You could initialize last to be pointing to head and then your if is redundant:

private Node<T> head = new Node<T>(null);
private Node<T> last = head;

public void add(T element) {
        Node<T> newNode = new Node<T>(element);
        last.next = newNode;
        last = last.next;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM