ArrayDeque 与 LinkedList 的区别

有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top

全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java 面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。 https://store.amazingmemo.com/chapterDetail/1685324709017001


1. 什么是ArrayDeque和LinkedList?

  • ArrayDeque:ArrayDeque是Java集合框架中的一个双端队列(deque)实现类。它基于数组实现,可以在两端高效地插入和删除元素。

  • LinkedList:LinkedList也是Java集合框架中的一个双端队列实现类。它基于链表实现,可以在任意位置高效地插入和删除元素。

2. 为什么需要ArrayDeque和LinkedList?

ArrayDeque:由于ArrayDeque底层使用数组实现,因此在随机访问元素时具有较好的性能。同时,ArrayDeque还提供了一些特殊方法,如栈操作( push/pop)和队列操作(offer/poll),使得它非常适用于需要高效插入和删除元素的场景。

LinkedList:LinkedList底层使用链表实现,因此在插入和删除元素时具有较好的性能。而且,LinkedList还提供了一些特殊方法,如addFirst/addLast/removeFirst/removeLast等,使得它非常适用于需要频繁在头部或尾部进行插入和删除操作的场景。

3. ArrayDeque和LinkedList的实现原理?

ArrayDeque:

  • ArrayDeque内部维护了一个循环数组,通过两个指针(front和rear) 来标记队列的头部和尾部。当向队列中添加元素时,rear指针向后移动;当从队列中删除元素时,front指针向后移动。如果数组满了,ArrayDeque会自动扩容。

  • ArrayDeque的底层数组长度是2的幂次方,这样可以通过位运算来实现循环队列的操作,提高性能。

LinkedList:

  • LinkedList内部使用双向链表来存储元素。每个节点都包含一个前驱节点和一个后继节点的引用。通过这种方式,LinkedList可以在任意位置高效地插入和删除元素。

  • LinkedList还有一个头结点和尾节点的引用,分别表示链表的头部和尾部。通过这两个引用,可以快速访问到链表的第一个和最后一个元素。

4. ArrayDeque和LinkedList的使用示例

ArrayDeque示例:

import java.util.ArrayDeque;

public class ArrayDequeExample {
    public static void main(String[] args) {
        ArrayDeque<Integer> deque = new ArrayDeque<>();
        
        // 添加元素
        deque.addFirst(1);
        deque.addLast(2);
        
        // 获取元素
        int first = deque.getFirst();
        int last = deque.getLast();
        
        System.out.println("First element: " + first); // 输出:First element: 1
        System.out.println("Last element: " + last); // 输出:Last element: 2
        
        // 删除元素
        deque.removeFirst();
        deque.removeLast();
        
        System.out.println("Size: " + deque.size()); // 输出:Size: 0
    }
}

LinkedList示例:

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        
        // 添加元素
        list.addFirst(1);
        list.addLast(2);
        
        // 获取元素
        int first = list.getFirst();
        int last = list.getLast();
        
        System.out.println("First element: " + first); // 输出:First element: 1
        System.out.println("Last element: " + last); // 输出:Last element: 2
        
        // 删除元素
        list.removeFirst();
        list.removeLast();
        
        System.out.println("Size: " + list.size()); // 输出:Size: 0
    }
}

5. ArrayDeque和LinkedList的优点

ArrayDeque的优点:

  • 随机访问元素时具有较好的性能,时间复杂度为O(1)。

  • 支持栈操作(push/pop)和队列操作(offer/poll),非常灵活。

LinkedList的优点:

  • 在任意位置插入和删除元素时具有较好的性能,时间复杂度为O(1)。

  • 提供了一些特殊方法(addFirst/addLast/removeFirst/removeLast等),方便在头部或尾部进行操作。

6. ArrayDeque和LinkedList的缺点

ArrayDeque的缺点:

  • 不支持线程安全,如果需要在多线程环境下使用,需要额外考虑同步问题。

LinkedList的缺点:

  • 访问指定位置的元素时性能较差,时间复杂度为O(n)。

  • 占用的内存空间相对较大,因为每个节点都需要额外的指针来维护链表结构。

7. ArrayDeque和LinkedList的使用注意事项

ArrayDeque的注意事项:

  • 不支持null元素,如果添加了null元素会抛出NullPointerException异常。

LinkedList的注意事项:

  • 在频繁插入和删除元素时,尽量避免在中间位置进行操作,因为这样会导致性能下降。

8. 总结

ArrayDeque和LinkedList是Java集合框架中的两种双端队列实现类。它们分别基于数组和链表实现,在不同的场景下具有不同的优势。ArrayDeque适用于需要高效随机访问元素和栈/队列操作的场景,而LinkedList适用于需要频繁在头部或尾部进行插入和删除操作的场景。在选择使用哪种实现类时,可以根据具体的需求来决定。

最后更新于