小酌Deque

刷力扣239的时候,发现使用一个数据结构Deque会让实现很简单。于是看源码学习一下。Deque继承Queue,但是包含更多方法。

Deque

Deque就是doulbe end queue,就是两端都可以操作的队列。

public interface Deque extends Queue {
void addFirst(E e);
void addLast(E e);
boolean offerFirst(E e);
......
}

ArrayDeque

让我们来看一下具体实现类ArrayDeque,可以看到,底层是用一个数组elements来实现的。先看几个Queue经典操作。

public class ArrayDeque extends AbstractCollection
                           implements Deque, Cloneable, Serializable
{
transient Object[] elements;

public void addFirst(E e) {
        if (e == null)
            throw new NullPointerException();
        elements[head = (head - 1) & (elements.length - 1)] = e;
        if (head == tail)
            doubleCapacity();
    }

public void addLast(E e) {
        if (e == null)
            throw new NullPointerException();
        elements[tail] = e;
        if ( (tail = (tail + 1) & (elements.length - 1)) == head)
            doubleCapacity();
    }
    Queue
public boolean offer(E e) {
        return offerLast(e);
    }
public E poll() {
        return pollFirst();
    }

public E peek() {
        return peekFirst();
    }
///Stack
 public void push(E e) {
        addFirst(e);
    }
public E pop() {
        return removeFirst();
    }

addFirst()

我们可以从这个方法得知这个数组是怎么储存数据的。
elements[head = (head - 1) & (elements.length - 1)] = e;长度只能是2的指数倍,所以elements.length - 1,就是低位都是1,比如长度为16,那么为01111(就相当于取模操作,主要为了解决负数-1). head刚进来初始化为0,0-1=-1,二进制为11111,&操作后为01111=15,所以第一个数被存在下标为15的地方也就是数组的尾巴,下一个add的数将会被存在(15-1)&(01111)=14,所以是倒着存的。以此类推。

这相当于是一个循环数组

addLast()

同理现在再看addLast()就很简单了,tail = (tail + 1) & (elements.length - 1),从前往后加对象。

相当于队列的操作

  1. poll() 可以看到调用了pollFirst(),顾名思义,就是把queue中第一个元素给poll了,那么肯定有pollLast(),poll掉最后一个元素。first是数组下标为0,last是数组下标为size的。
  2. peek()调用了peekFirst(),同理还可以使用peekLast()
  3. offer()调用了offerLast(),就是往数组尾巴上加入元素。

相当于stack的操作

  1. push()
  2. peek()
  3. pop()

你可能感兴趣的:(源码,夯实java核心基础,java)