简体   繁体   English

在Java中将元素添加到单链列表

[英]Adding an element to a singly linked list in Java

I'm implementing a singly linked list in Java. 我正在用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. 我对这段代码if (head.next == null)是,每次添加元素时都需要检查if (head.next == null) 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; 在许多情况下,“良好的OO设计”使您无需进行if / else检查。 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. 然后,在最初生成该“另一个对象”并将其提供给您的客户代码的代码中,“隐藏”了“ if”。 (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. 如果经常调用您的代码,而这很重要,那么无论如何JIT都会启动,并且可能会创建在大多数情况下直接采用正确分支的代码。

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: 您可以将last初始化为指向head,然后if是否多余:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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