2026/2/11 4:12:01
网站建设
项目流程
微豆网络科技有限公司网页设计,南昌网站排名优化软件,手机app编程教程,网站建设衤金手指谷哥十四Java ArrayList 与 LinkedList#xff1a;实现原理与性能对比ArrayList 和 LinkedList 都实现了 List 接口#xff0c;提供了有序的集合操作#xff0c;但它们的底层数据结构和操作实现方式完全不同#xff0c;因此在性能和使用场景上有很大差异。通过对比两者的实现#…JavaArrayList与LinkedList实现原理与性能对比ArrayList和LinkedList都实现了List接口提供了有序的集合操作但它们的底层数据结构和操作实现方式完全不同因此在性能和使用场景上有很大差异。通过对比两者的实现可以帮助我们在不同场景下做出更合适的选择。1.ArrayList和LinkedList的设计思想ArrayList和LinkedList都是List接口的实现类但它们的设计思想和适用场景有所不同ArrayList基于动态数组实现适合频繁访问元素的场景。底层存储是一个数组访问元素的时间复杂度为O(1)。插入和删除元素时可能需要移动数组中的元素时间复杂度为O(n)。LinkedList基于双向链表实现适合频繁插入和删除元素的场景。每个元素是一个节点包含指向前后节点的引用。插入和删除元素时不需要移动其他元素时间复杂度为O(1)。访问元素时需要遍历链表时间复杂度为O(n)。2.ArrayList源码实现ArrayList底层基于数组实现支持动态扩容。初始化与扩容ensureCapacity用于判断当前数组的容量是否足够如果不够则调用grow方法扩容。grow通过Arrays.copyOf创建一个更大的数组并将原有数组的元素拷贝过去扩容后的容量为原容量的1.5倍。示例代码ArrayList扩容java复制private void ensureCapacityInternal(int minCapacity) { if (minCapacity elementData.length) { grow(minCapacity); } } private void grow(int minCapacity) { int oldCapacity elementData.length; int newCapacity oldCapacity (oldCapacity 1); // 扩容为原容量的1.5倍 elementData Arrays.copyOf(elementData, newCapacity); }3.LinkedList源码实现LinkedList底层基于双向链表实现每个节点包含数据和指向前后节点的指针。节点定义java复制private static class NodeE { E item; // 数据 NodeE next; // 指向下一个节点 NodeE prev; // 指向前一个节点 Node(NodeE prev, E element, NodeE next) { this.item element; this.next next; this.prev prev; } }节点插入操作linkLast将新元素插入到链表的末尾。链表的头节点first和尾节点last用于维护链表的开始和结束。示例代码LinkedList插入java复制public void add(E e) { linkLast(e); } void linkLast(E e) { final NodeE l last; final NodeE newNode new Node(l, e, null); last newNode; if (l null) first newNode; else l.next newNode; size; }4. 添加元素的性能比较ArrayList在末尾添加元素时时间复杂度为O(1)。如果数组满了会进行扩容扩容的时间复杂度为O(n)。添加流程add(E e)调用ensureCapacity()检查是否需要扩容。如果不需要扩容将元素添加到数组的最后一个位置并增加size。LinkedList插入元素的时间复杂度为O(1)因为只需要修改前后节点的指针。添加流程add(E e)调用linkLast(E e)方法将元素插入到链表的尾部。创建新节点并更新前后节点的指针最后增加size。5. 查找元素的性能比较ArrayList查找元素时时间复杂度为O(1)直接通过索引访问数组元素。LinkedList查找元素时时间复杂度为O(n)需要从头到尾遍历链表。6. 删除元素的性能比较ArrayList删除元素时删除位置之后的所有元素需要向前移动时间复杂度为O(n)。删除流程java复制public boolean remove(Object o) { if (o null) { for (int i 0; i size; i) { if (elementData[i] null) { fastRemove(i); // 调用fastRemove移除元素 return true; } } } else { for (int i 0; i size; i) { if (o.equals(elementData[i])) { fastRemove(i); // 调用fastRemove移除元素 return true; } } } return false; }LinkedList删除元素时只需修改前后节点的指针时间复杂度为O(1)。但需要遍历链表找到要删除的节点查找的时间复杂度为O(n)。删除流程java复制public E remove(int index) { checkElementIndex(index); // 索引越界检查 NodeE x node(index); // 找到要删除的节点 E element x.item; unlink(x); // 移除节点 return element; } void unlink(NodeE x) { final NodeE next x.next; final NodeE prev x.prev; if (prev null) first next; else prev.next next; if (next null) last prev; else next.prev prev; x.item null; size--; }7. 适用场景总结ArrayList适用场景适合频繁访问元素的场景尤其是需要随机访问时。在大量插入和删除操作时性能较差因为需要移动数组元素。LinkedList适用场景适合频繁插入和删除操作的场景尤其是操作链表两端时。在大量访问元素时性能较差因为需要逐个节点遍历。