Java双端队列-ArrayDeque的使用

1、概览

本篇,我们将介绍ArrayDeque的使用方法-ArrayDeque是Deque的一个实现。ArrayDeque俗称数组双端队列,是一种允许我们从俩端进行存取操作的可扩容数组。

ArrayDeque既可以作为Stack使用(Last-In-First-Out) 又可以作为Queue使用(First-In-First-Out)。

2、API

针对于每个操作,我们基本上都有俩个可选择的API,第一组API方法在操作失败时,会抛出异常。另一组则会返回一个状态或一个值。

操作 API API(会抛出异常)
从头部插入元素 offerFirst(e) addFirst(e)
从头部移出元素 pollFirst(e) removeFirst(e)
从头部获取元素 peekFirst(e) peekFirst(e)
从尾部插入元素 offerLast(e) addLast(e)
从尾部移出元素 pollLast(e) removeLast(e)
从尾部获取元素 peekLast(e) peekLast(e)

3、使用方法

下面,我们将通过几个示例来看一下ArrayDeque的用法。

3.1 ArrayDeque作为栈使用

接下来,我们把ArrayDeque当做Stack用-并向其中push一个元素

public static void whenPush_addsAtFirst(){

        Deque stack = new ArrayDeque<>();
        stack.push("first");
        stack.push("second");

        System.out.println(stack.getFirst());

}

当用作Stack时,我们如何从中pop出一个元素:

public static void whenPop_removesLast(){

       Deque stack = new ArrayDeque<>();

       stack.push("first");
       stack.push("second");

       System.out.println(stack.pop());
}

当stack为空时,pop方法会抛出NoSuchElementException异常。

3.2 ArrayDeque作为队列使用

接下来,我们看把ArrayDeque当做Queue使用时,如何向其中添加一个元素:

public static void whenOffer_addsAtLast(){

        Deque  queue = new ArrayDeque<>();
        queue.offer("first");
        queue.offer("second");

        System.out.println(queue.getLast());
    }

当把ArrayDeque作为Queue使用时,如何从队列中获取元素:

public static void whenPoll_removesFirst(){

        Deque  queue = new ArrayDeque<>();
        queue.offer("first");
        queue.offer("second");

        System.out.println(queue.poll());
    }

若队列为空的话,poll方法将返回null值。

4、ArrayDeque的实现原理

原理

ArrayDeque的底层是由一个数组来实现的,这个数组会在其塞满的时候,把容量扩大一倍。该数组初始化大小为16,它通过维护俩个指针:head、tail实现了双端队列。

4.1 ArrayDeque作为栈的实现原理

作为栈

正如图上所示,当用户使用push方法向其中添加元素时,它会把head头指针向前移动一位。
当我们从栈中弹出一个元素时,它会把head位置处的元素设置为null(这样的话,此元素就可以被垃圾回收),并且把head指针向后移动一位。

4.2 ArrayDeque作为队列的实现原理

作为队列

如上图所示,使用offer向队列中添加元素,tail尾指针会向后移动一位。而当用户从队列中拉取一个元素时,它会把head位置处的元素设置为null,并且把head指针向后移动一位。

4.3 ArrayDeque的注意点

最后,有几个注意点我们需要记住:

. ArrayDeque不是线程安全的

. ArrayDeque不能存储Null值

. 相较于同步栈来说,ArrayDeque的速度相当快

. ArrayDeque比LinkedList速度更快

. 大多数操作的时间复杂度都是常数

. ArrayDeque的Iterator是fail-fast的

. 当添加元素时,如果head指针和tail指针指向同一位置,ArrayDeque会自动把容量扩大一倍

5、总结

全部代码如下:

public class ArrayDequeTests {


    public static void main(String[] args) throws Exception{

        //whenPush_addsAtFirst();
        //whenPop_removesLast();
        //whenOffer_addsAtLast();
        whenPoll_removesFirst();
    }

    public static void whenPush_addsAtFirst(){

        Deque stack = new ArrayDeque<>();
        stack.push("first");
        stack.push("second");

        System.out.println(stack.getFirst());

    }


    public static void whenPop_removesLast(){

        Deque stack = new ArrayDeque<>();

        stack.push("first");
        stack.push("second");

        System.out.println(stack.pop());
    }


    public static void whenOffer_addsAtLast(){

        Deque  queue = new ArrayDeque<>();
        queue.offer("first");
        queue.offer("second");

        System.out.println(queue.getLast());
    }


    public static void whenPoll_removesFirst(){

        Deque  queue = new ArrayDeque<>();
        queue.offer("first");
        queue.offer("second");

        System.out.println(queue.poll());
    }


}


以上就是关于ArrayDeque的简单介绍。

6、参考文献

  1. oracle-javase7-apidoc

  2. baeldung-java-ArrayDeque

  3. stackoverflow-why-is-arraydeque-better-than-linkedlist

  4. java-collections-overview

你可能感兴趣的:(Java双端队列-ArrayDeque的使用)