java集合Collection总结:栈、队列

java集合Collection总结:栈、队列

栈(Stack) - 后进先出

首选ArrayDeque,其次LinkedList,不推荐Stack
Stack实现Vector接口。Vector底层使用的是Object动态数组,Vector是线程安全的,但效率较低

ArrayDeque和LinkedList的区别

ArrayDeque:
  • 数组结构
  • 插入元素不能是null
  • 无法确定数据量时,后期扩容会影响效率
LinkedList:
  • 链表结构
  • 插入元素能为null
  • 无法确定数据量时,有更好的表现

StackAPI

methodfunctionreturn
push(E)添加元素E
peek()得到栈顶元素E
pop()删除元素E
search(Object)查找元素int
empty()判断是否为空boolean
size()栈的大小int
push(E) 和 add(E)区别

push()底层使用的是 Vector 中的add()push()的返回值是添加的元素,add()的返回值是是否添加成功

push()底层源码
public E push(E item) {
    addElement(item);

    return item;
}

public synchronized void addElement(E obj) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = obj;
}
add()底层源码
public synchronized boolean add(E e) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = e;
    return true;
}
peek()底层源码
public synchronized E peek() {
    int     len = size();

    if (len == 0)
        throw new EmptyStackException();
    return elementAt(len - 1);
}
pop()底层源码
public synchronized E pop() {
    E       obj;
    int     len = size();

    obj = peek();
    removeElementAt(len - 1);

    return obj;
}

public synchronized void removeElementAt(int index) {
    modCount++;
    if (index >= elementCount) {
        throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
    }
    else if (index < 0) {
        throw new ArrayIndexOutOfBoundsException(index);
    }
    int j = elementCount - index - 1;
    if (j > 0) {
        System.arraycopy(elementData, index + 1, elementData, index, j);
    }
    elementCount--;
    elementData[elementCount] = null; /* to let gc do its work */
}
search()底层源码
    public synchronized int search(Object o) {
        int i = lastIndexOf(o);

        if (i >= 0) {
            return size() - i;
        }
        return -1;
    }
empty()底层源码
public boolean empty() {
    return size() == 0;
}

LinkedList实现栈

LinkedList是一个双向链表,非线程安全,可以作为栈使用

API

methodfunctionreturn
push(E)添加元素void
peek()得到栈顶元素E
pop()删除元素E
isEmpty()判断是否为空boolean
push(E)底层源码
public void push(E e) {
    addFirst(e);
}

public void addFirst(E e) {
    linkFirst(e);
}

private void linkFirst(E e) {
    final Node<E> f = first;
    final Node<E> newNode = new Node<>(null, e, f);
    first = newNode;
    if (f == null)
        last = newNode;
    else
        f.prev = newNode;
    size++;
    modCount++;
}
peek()底层源码
public E peek() {
    final Node<E> f = first;
    return (f == null) ? null : f.item;
}
pop()底层源码
public E pop() {
    return removeFirst();
}

public E removeFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}

private E unlinkFirst(Node<E> f) {
    // assert f == first && f != null;
    final E element = f.item;
    final Node<E> next = f.next;
    f.item = null;
    f.next = null; // help GC
    first = next;
    if (next == null)
        last = null;
    else
        next.prev = null;
    size--;
    modCount++;
    return element;
}    

队列

Queue同样继承了Collection接口,Queue是一个接口,不能直接实例化。
Queue接口API:

methodfunctionreturn
offer(E)添加元素boolean
poll()删除元素E
peek()获取队头元素E

其中add(E)offer(E)poll()remove(),peek()element()作用一样

非阻塞队列

非阻塞队列是使用CAS(compare and set)机制实现,类似 volatile,并发性能好。

常用类注意事项
PriorityQueue基于优先级的无界优先级队列
ConcurrentLinkedDeque基于双向链表结构的无界并发队列

阻塞队列(BlockingQueue)

阻塞队列是一个可以阻塞的先进先出集合,比如某个线程在空队列获取元素时、或者在已存满队列存储元素时,都会被阻塞

常用类注意事项
ArrayBlockingQueue基于数组的有界阻塞队列,必须指定大小
LinkedBlockingQueue基于单链表的无界阻塞队列,不需指定大小
PriorityBlockingQueue基于最小二叉堆的无界、优先级阻塞队列
DelayQueue基于延迟、优先级、无界阻塞队列
SynchronousQueue基于 CAS 的阻塞队列

双端队列(Deque)

Deque 是一个既可以在头部操作元素,又可以为尾部操作元素,俗称为双向(双端)队列。Deque 继承自 Queue,Deque 实现类有 LinkedList、 ArrayDeque、ConcurrentLinkedDeque 等等。在将List篇的时候,里面就说LinkedList是一种双向队列,其实它也是Deque的一种实现方式。

常用类注意事项
LinkedList基于单链表的无界双端队列,允许元素为 null
ArrayDeque基于数组的有界双端队列,不允许null。不是线程安全的。当作为栈使用时,性能比Stack好;当作为队列使用时,性能比LinkedList好

ArrayDeque

  1. ArrayDeque是 Deque接口的一个实现,使用了可变数组,所以没有容量上的限制。
  2. ArrayDeque是线程不安全的,在没有外部同步的情况下,不能再多线程环境下使用。ArrayDeque不支持 null值。
  3. ArrayDeque是 Deque的实现类,可以作为栈来使用,效率高于 Stack;也可以作为队列来使用,效率高于 LinkedList。
  4. ArrayDeque 是 Java 集合中双端队列的数组实现,双端队列的链表实现(LinkedList)
 1.添加元素
    addFirst(E e)在数组前面添加元素
    addLast(E e)在数组后面添加元素
    offerFirst(E e) 在数组前面添加元素,并返回是否添加成功
    offerLast(E e) 在数组后天添加元素,并返回是否添加成功
 
2.删除元素
    removeFirst()删除第一个元素,并返回删除元素的值,如果元素为null,将抛出异常
    pollFirst()删除第一个元素,并返回删除元素的值,如果元素为null,将返回null
    removeLast()删除最后一个元素,并返回删除元素的值,如果为null,将抛出异常
    pollLast()删除最后一个元素,并返回删除元素的值,如果为null,将返回null
    removeFirstOccurrence(Object o) 删除第一次出现的指定元素
    removeLastOccurrence(Object o) 删除最后一次出现的指定元素
   
3.获取元素
    getFirst() 获取第一个元素,如果没有将抛出异常
    getLast() 获取最后一个元素,如果没有将抛出异常
    peekFirst() 获取第一个元素,如果元素为null,将返回null
    peekLast() 获取最后一个元素,如果元素为null,将返回null
   
4.队列操作
    add(E e) 在队列尾部添加一个元素
    offer(E e) 在队列尾部添加一个元素,并返回是否成功
    remove() 删除队列中第一个元素,并返回该元素的值,如果元素为null,将抛出异常(其实底层调用的是removeFirst())
    poll()  删除队列中第一个元素,并返回该元素的值,如果元素为null,将返回null(其实调用的是pollFirst())
    element() 获取第一个元素,如果没有将抛出异常
    peek() 获取第一个元素,如果返回null
 
5.栈操作
    push(E e) 栈顶添加一个元素
    pop() 移除栈顶元素,如果栈顶没有元素将抛出异常
        
6.其他
    size() 获取队列中元素个数
    isEmpty() 判断队列是否为空
    iterator() 迭代器,从前向后迭代
    descendingIterator() 迭代器,从后向前迭代
    contain(Object o) 判断队列中是否存在该元素
    toArray() 转成数组
    clear() 清空队列
    clone() 克隆(复制)一个新的队列
  • 33
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值