本文详解双向链表的核心设计原则,指出常见错误(如节点与链表职责混淆、缺少容量管理、构造函数语法错误等),并提供可扩展、线程安全友好的标准实现,支持泛型和显式容量限制。
本文详解双向链表的核心设计原则,指出常见错误(如节点与链表职责混淆、缺少容量管理、构造函数语法错误等),并提供可扩展、线程安全友好的标准实现,支持泛型和显式容量限制。
在 Java 中实现双向链表时,初学者常将链表逻辑与节点结构混为一谈——例如在链表类中直接定义 previous 和 next 字段,或误用构造函数语法(如 class LRU(int capacity) 是非法的 Java 语法)。正确的分层设计应严格分离关注点:Node 类仅负责存储数据与前后引用;DoublyLinkedList 类负责维护头尾指针、大小统计及容量策略。
以下是符合 Java 规范、具备容量控制能力的双向链表完整实现(已升级为泛型版本,便于复用):
public class DoublyLinkedList<T> { private final int capacity; // 最大容量(0 表示无限制) private int size; private Node<T> head; private Node<T> tail; // 构造函数:支持指定容量(传入 <= 0 表示无容量限制) public DoublyLinkedList(int capacity) { this.capacity = capacity; this.size = 0; this.head = null; this.tail = null; } // 在链表尾部添加元素(LIFO 默认行为) public boolean add(T data) { if (capacity > 0 && size >= capacity) { return false; // 已达容量上限,拒绝插入 } Node<T> newNode = new Node<>(null, data, null); if (head == null) { head = tail = newNode; } else { tail.next = newNode; newNode.previous = tail; tail = newNode; } size++; return true; } // 在链表头部添加元素(适用于 LRU 等场景) public boolean addFirst(T data) { if (capacity > 0 && size >= capacity) { return false; } Node<T> newNode = new Node<>(null, data, head); if (head != null) { head.previous = newNode; } else { tail = newNode; // 原链表为空,新节点同时是 tail } head = newNode; size++; return true; } // 获取当前元素数量 public int size() { return size; } // 判断是否已满(仅当设置了正容量时有效) public boolean isFull() { return capacity > 0 && size >= capacity; } // 内部静态 Node 类:封装数据与双向引用 private static class Node<T> { Node<T> previous; T data; Node<T> next; Node(Node<T> previous, T data, Node<T> next) { this.previous = previous; this.data = data; this.next = next; } }}
✅ 关键修正说明:
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
该设计兼顾清晰性、可维护性与实用性,是构建高性能缓存(如 LRU)、队列或有序列表的理想基础结构。