S SmartDocs
シリーズ: Angelia java 98 行 · 更新日 2026-09-27

LinkedSimpleList.java

Angelia/Java/Week_6_7/code/02_adt_interfaces/LinkedSimpleList.java

import java.util.Objects;

/**
 * SimpleList 的鏈結串列實作。
 *
 * 使用「內部類別」(inner class)Node 把節點藏在類別裡:
 * 使用者只看到 SimpleList 的四個操作,完全不需要知道 Node 的存在,
 * 也不必自己區分「空串列」與「非空串列」——這些細節全部被封裝起來了。
 *
 * 資料不變量:size 等於從 head 出發能走到的節點數。
 */
public class LinkedSimpleList implements SimpleList {

    /** 私有內部類別:外界看不到,也不需要看到。 */
    private class Node {
        Object value;
        Node next;

        Node(Object value, Node next) {
            this.value = value;
            this.next = next;
        }
    }

    private Node head = null;
    private int size = 0;

    @Override
    public int size() {
        return this.size;
    }

    @Override
    public Object get(int index) {
        if (index < 0 || index >= this.size) {          // 檢查前置條件
            throw new IndexOutOfBoundsException(
                    "index " + index + " 超出範圍 [0, " + this.size + ")");
        }
        Node current = this.head;
        int i = 0;
        while (i < index) {                              // 往前走 index 步
            current = current.next;
            i = i + 1;
        }
        return current.value;
    }

    @Override
    public void add(Object o) {
        Node node = new Node(o, null);
        if (this.head == null) {                         // 空串列:新節點就是 head
            this.head = node;
        } else {                                         // 否則走到最後一個節點,接上去
            Node current = this.head;
            while (current.next != null) {
                current = current.next;
            }
            current.next = node;
        }
        this.size = this.size + 1;
    }

    @Override
    public void remove(Object o) {
        if (this.head == null) {
            return;                                      // 空串列:沒東西可移除
        }
        if (Objects.equals(this.head.value, o)) {        // Objects.equals 能安全處理 null
            this.head = this.head.next;                  // 移除的是第一個節點
            this.size = this.size - 1;
            return;
        }
        Node prev = this.head;
        while (prev.next != null) {
            if (Objects.equals(prev.next.value, o)) {
                prev.next = prev.next.next;              // 跳過被移除的節點
                this.size = this.size - 1;
                return;
            }
            prev = prev.next;
        }
    }

    /** 方便除錯用:印成 [a, b, c] 的形式。 */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("[");
        Node current = this.head;
        while (current != null) {
            sb.append(current.value);
            if (current.next != null) {
                sb.append(", ");
            }
            current = current.next;
        }
        return sb.append("]").toString();
    }
}

関連記事