将元素添加到 Java 中的单向链表
Adding an element to a singly linked list in Java
我正在 Java 中实现一个单向链表。我不喜欢这段代码的地方是每次添加元素时都需要检查 if (head.next == null)
。但条件只满足一次,即添加第一个元素时。
有没有办法实现没有这种条件的单向链表?
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();
}
}
}
在很多情况下,"good OO design" 允许您无需 if/else 检查;最常见的是使用某种形式的多态性。
意思是:不是向某个对象询问某些 属性,然后在您的客户端代码中对此做出决定,而是以某种方式确保您的客户端代码可以简单地调用其他对象的方法。然后,"if" 是最初生成 "other object" 并将其提供给您的客户端代码的代码中的 "hidden"。 (你会在这些 videos 中找到一些很好的例子是如何工作的)。
但是 - 我认为在这种情况下这显然是矫枉过正!
重点是:从可读性的角度来看,一次检查确实没有什么坏处(也许您可以将事情重构为更多方法)。性能......也无所谓。如果您的代码被调用得如此频繁以至于这很重要,那么 JIT 无论如何都会启动,并且可能会创建在大多数情况下直接采用正确分支的代码。
因此:这是一个很好的实现;我认为你不应该担心这个 if-check there!
您可以将 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;
}
我正在 Java 中实现一个单向链表。我不喜欢这段代码的地方是每次添加元素时都需要检查 if (head.next == null)
。但条件只满足一次,即添加第一个元素时。
有没有办法实现没有这种条件的单向链表?
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();
}
}
}
在很多情况下,"good OO design" 允许您无需 if/else 检查;最常见的是使用某种形式的多态性。
意思是:不是向某个对象询问某些 属性,然后在您的客户端代码中对此做出决定,而是以某种方式确保您的客户端代码可以简单地调用其他对象的方法。然后,"if" 是最初生成 "other object" 并将其提供给您的客户端代码的代码中的 "hidden"。 (你会在这些 videos 中找到一些很好的例子是如何工作的)。
但是 - 我认为在这种情况下这显然是矫枉过正!
重点是:从可读性的角度来看,一次检查确实没有什么坏处(也许您可以将事情重构为更多方法)。性能......也无所谓。如果您的代码被调用得如此频繁以至于这很重要,那么 JIT 无论如何都会启动,并且可能会创建在大多数情况下直接采用正确分支的代码。
因此:这是一个很好的实现;我认为你不应该担心这个 if-check there!
您可以将 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;
}