Java 集合类 8-栈,队列

时间:2022-02-06 17:39:04

1. 栈

 栈是一种先进后出的数据结构 浏览器的后退、编辑器的撤销、安卓Activity的返回等都属于栈的功能。

 在Java集合中提供有Stack类,这个类是集合类Vector的子类。需要注意的是,关于栈的方法并不是Vector类或者List接口给出的,而是Stack类自己定义的。

 接下来介绍栈的三个常用方法。

// 入栈
public E push(E item) {
    // 将新元素尾添进栈
    addElement(item);
    // 返回添加的元素(方便操作)
    return item;
}

// 出栈
public synchronized E pop() {
    E       obj;
    // 获取当前栈的大小
    int     len = size();

    // 获取栈顶元素
    obj = peek();
    // 删除栈顶元素,尾删
    removeElementAt(len - 1);
    // 返回这个删除的元素
    return obj;
}

// 得到栈顶元素
public synchronized E peek() {
    int     len = size();
    // 如果要得到空栈的栈顶元素,抛出异常
    if (len == 0)
        throw new EmptyStackException();
    // 返回栈顶元素
    return elementAt(len - 1);
}

 使用如下:

import java.util.Stack;

public class Test {
    public static void main(String[] args) {
        Stack<Character> stack = new Stack<>();
        // 元素入栈
        stack.push('a');
        stack.push('b');
        stack.push('c');
        stack.push('d');

        try {
            // 栈空时会抛出 EmptyStackException 异常进入catch块,从而结束打印
            while(stack.peek() != null) {
                // 出栈栈顶元素,并打印出栈元素
                System.out.println(stack.pop());
            }
        } catch(Exception e) {
            System.out.println("栈空");
        }
    }
}

运行结果,后入先出:

Java 集合类 8-栈,队列

 特别注意,对空栈使用peek()时,会抛出一个异常,所以这里遍历栈的操作要放在try-catch块中。

2. 队列

 与栈对应,队列是一种先进先出的数据结构,由于这种特性,所以队列被广泛应用于高并发的场景下。

Java 集合类 8-栈,队列

 java.util包中提供了一个Queue接口来实现队列操作。并且在Queue接口子类中,有我们集合类的一个老面孔存在——LinkedList类。Queue接口继承关系如下:

Java 集合类 8-栈,队列

 从上图可以看出,其实Queue接口也是集合类的一员。

 通常在进行队列操作时,我们都直接使用LinkedList进行队列创建。LinkedList中包含的队列操作是Queue接口定义的,方法如下:

// 向队列中添加元素,尾添
public boolean add(E e) {
    // 尾添元素
    linkLast(e);
    return true;
}

// 队首元素出队列
public E poll() {
    final Node<E> f = first;
    // 队首为空,返回null,不为空返回队首元素
    return (f == null) ? null : unlinkFirst(f);
}

// 获取队首元素
public E peek() {
    final Node<E> f = first;
    // 空队列返回null,否则返回队首元素
    return (f == null) ? null : f.item;
}

 使用如下:

import java.util.LinkedList;
import java.util.Queue;

public class Test {
    public static void main(String[] args) {
        // LinkedList是Queue的子类,一般采用其进行队列操作
        Queue<Character> queue = new LinkedList<>();
        queue.add('a');
        queue.add('b');
        queue.add('c');
        queue.add('d');

        // LinkedList的peek()方法在空队列时会返回一个null
        while(queue.peek() != null) {
            // 出队列队首元素并打印
            System.out.println(queue.poll());
        }
    }
}

运行结果,先入先出:

Java 集合类 8-栈,队列

 线程安全的队列+生产消费者模型 = 简化版的卡夫卡。