聊一聊java.util包中的Queue、Deque以及Stack分别是什么

先来了解几个概念:

什么是队列?

队列(Queue)是一种特殊类型的线性数据结构,它遵循FIFO(First In First Out,先进先出)的原则。在队列中,元素的添加(称为入队,enqueue)通常发生在队列的尾部,而元素的移除(称为出队,dequeue)则发生在队列的头部。这种特性使得队列在处理需要按照特定顺序(即元素进入队列的顺序)处理的元素时非常有用。

队列的主要类型包括以下几种:

  1. 普通队列(Simple Queue):这是最基本的队列类型,只支持在队列尾部入队和在队列头部出队操作。它通常用于需要按照元素到达的顺序处理元素的场景,如打印任务队列、线程池的任务调度等。

  2. 循环队列(Circular Queue):循环队列是普通队列的一种优化形式,它使用循环索引来管理队列的头部和尾部,从而避免了在队列满或空时需要进行额外的空间分配或检查。循环队列可以有效地利用存储空间,提高队列操作的效率。

  3. 优先级队列(Priority Queue):优先级队列是一种特殊的队列,其中每个元素都关联一个优先级。优先级最高的元素将首先出队,而不是按照它们进入队列的顺序。这种队列类型常用于需要按照元素的优先级进行处理的场景,如任务调度、事件处理等。

  4. 双端队列(Deque,Double-Ended Queue):虽然双端队列不是传统意义上的队列(因为它支持在队列的两端进行入队和出队操作),但它在某些情况下可以被视为队列的一种扩展。双端队列在队列的前端和后端都可以进行元素的添加和删除,这使得它在某些特定场景(如实现双向的FIFO结构)下非常有用。

队列的主要操作包括:

  • 入队(Enqueue):将元素添加到队列的队尾。
  • 出队(Dequeue):从队列的队头移除元素,并返回该元素。
  • 判空(Is Empty):检查队列是否为空,即没有元素。
  • 获取队头元素(Peek or Front):查看但不移除队头的元素。

什么是栈?

栈(Stack)是一种特殊的线性数据结构,它遵循LIFO(Last In First Out,后进先出)的原则。在栈中,元素的添加和移除都发生在同一端,通常被称为栈顶。栈底是栈中固定的一端,不允许进行添加或移除操作。

栈的主要操作包括:

  • 入栈(Push):将元素添加到栈顶。
  • 出栈(Pop):从栈顶移除元素,并返回该元素。出栈后,原栈顶元素下一个元素成为新的栈顶。
  • 查看栈顶元素(Top 或 Peek):返回栈顶元素,但不改变栈的状态。
  • 判空(Is Empty):检查栈是否为空,即没有任何元素。

由于栈的后进先出特性,它常被用于需要保存临时状态或撤销操作的场景。例如,在函数调用中,栈被用来保存局部变量和返回地址;在解析表达式时,栈被用来保存操作符和操作数。

再来看看java.util包中的Queue、Deque、以及Stack分别是什么

java.util.Queue

Queue,jdk1.5引入,继承自Collection接口,单向队列,遵循FIFO(First In First Out,先进先出)原则,入队操作发生在队列尾部,出队操作发生在队列头部。

Queue方法说明:

  • Insert-插入类方法:

        add(E e):将指定的元素插入到队列中,如果插入成功则返回true,否则抛出一个异常

    /**
     * Inserts the specified element into this queue if it is possible to do so
     * immediately without violating capacity restrictions, returning
     * {@code true} upon success and throwing an {@code IllegalStateException}
     * if no space is currently available.
     *
     * @param e the element to add
     * @return {@code true} (as specified by {@link Collection#add})
     * @throws IllegalStateException if the element cannot be added at this
     *         time due to capacity restrictions
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this queue
     * @throws NullPointerException if the specified element is null and
     *         this queue does not permit null elements
     * @throws IllegalArgumentException if some property of this element
     *         prevents it from being added to this queue
     */
    boolean add(E e);

        offer(E e):将指定的元素插入到队列中,如果插入成功则返回true,否则返回false

    /**
     * Inserts the specified element into this queue if it is possible to do
     * so immediately without violating capacity restrictions.
     * When using a capacity-restricted queue, this method is generally
     * preferable to {@link #add}, which can fail to insert an element only
     * by throwing an exception.
     *
     * @param e the element to add
     * @return {@code true} if the element was added to this queue, else
     *         {@code false}
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this queue
     * @throws NullPointerException if the specified element is null and
     *         this queue does not permit null elements
     * @throws IllegalArgumentException if some property of this element
     *         prevents it from being added to this queue
     */
    boolean offer(E e);
  • Remove-移除类方法:

        remove():移除并返回队列的头部元素,如果队列为空则抛出一个异常

    /**
     * Retrieves and removes the head of this queue.  This method differs
     * from {@link #poll poll} only in that it throws an exception if this
     * queue is empty.
     *
     * @return the head of this queue
     * @throws NoSuchElementException if this queue is empty
     */
    E remove();

        poll():移除并返回队列的头部元素,如果队列为空则返回null

    /**
     * Retrieves and removes the head of this queue,
     * or returns {@code null} if this queue is empty.
     *
     * @return the head of this queue, or {@code null} if this queue is empty
     */
    E poll();
  • Examine-检验类方法:(查看元素但不移除)

        element():返回队列的头部元素,但不移除。如果队列为空则抛出一个异常

    /**
     * Retrieves, but does not remove, the head of this queue.  This method
     * differs from {@link #peek peek} only in that it throws an exception
     * if this queue is empty.
     *
     * @return the head of this queue
     * @throws NoSuchElementException if this queue is empty
     */
    E element();

        peek():返回队列的头部元素,但不移除。如果队列为空则返回null

    /**
     * Retrieves, but does not remove, the head of this queue,
     * or returns {@code null} if this queue is empty.
     *
     * @return the head of this queue, or {@code null} if this queue is empty
     */
    E peek();
  • 其他常用方法:

        除了上同Queue接口中定义的三类方法外,由于Queue继承自Collection接口,所以Collection的接口Queue自然也支持,如:

    contains(Object o): 判断队列中是否包含指定元素。

    isEmpty(): 判断队列是否为空。

    size(): 返回队列中的元素个数。

    toArray(): 将队列中的元素以数组的形式返回。

Queue常见实现类:

注意:

java.util.Deque

Deque,jdk1.6引入,继承自Queue接口,双端队列(Double Ended Queue),即:除了继承自Queue的方法外,它还支持在队列两端进行元素的添加、删除和检索操作。

A linear collection that supports element insertion and removal at both ends. 
The name deque is short for "double ended queue" and is usually pronounced "deck".
Most Deque implementations place no fixed limits on the number of elements they may contain, but this interface supports capacity-restricted deques as well as those with no fixed size limit

 Deque常用方法:(相比Queue,多了首-First,尾-Last相关的操作)

First Element(Head,First)Last Element(Tail,Last)
Throws ExceptionSpecial ValueThrows ExceptionSpecial Value
InsertaddFirst(E e)offerFirst(E e)addLast()offerLast()
RemoveremoveFirst()pollFirst()removeLast()pollLast()
ExaminegetFirst()peekFirst()getLast()peekLast()

以上表格中展示的为双端队列的方法。

当然,它也支持Queue的方法:add(E e)/offer(E e), remove()/poll(), element()/peek()

同时,由于它是一个双端队列,支持从头、尾操作,自然也可以用来支持栈(Stack)操作,如:

push(E e):等价于addFirst(E e),在队列的头部插入元素。如果队列已满,会抛出异常。

pop():等价于removeFirst(),移除并返回队列的头部元素。如果队列为空,会抛出异常。

同样,它也支持Collection的方法:size(),contains(o),remove(o)...

java.util.Stack

 

以上为Stack类图,再看一下它的javadoc注解:

/**
 * The <code>Stack</code> class represents a last-in-first-out
 * (LIFO) stack of objects. It extends class <tt>Vector</tt> with five
 * operations that allow a vector to be treated as a stack. The usual
 * <tt>push</tt> and <tt>pop</tt> operations are provided, as well as a
 * method to <tt>peek</tt> at the top item on the stack, a method to test
 * for whether the stack is <tt>empty</tt>, and a method to <tt>search</tt>
 * the stack for an item and discover how far it is from the top.
 * <p>
 * When a stack is first created, it contains no items.
 *
 * <p>A more complete and consistent set of LIFO stack operations is
 * provided by the {@link Deque} interface and its implementations, which
 * should be used in preference to this class.  For example:
 * <pre>   {@code
 *   Deque<Integer> stack = new ArrayDeque<Integer>();}</pre>
 *
 * @author  Jonathan Payne
 * @since   JDK1.0
 */
public
class Stack<E> extends Vector<E>

Stack,jdk1.0起便存在,继承自Vector,栈,遵循后进先出(LIFO)原则。

Stack类常用方法:

  1. push(E item):

    • 此方法用于将指定的元素推入此栈。
    • 参数:要推入栈的元素。
    • 返回值:被推入栈的元素。
  2. pop():

    • 此方法用于移除并返回此栈的顶部对象。
    • 如果此栈为空,则抛出EmptyStackException
    • 返回值:栈顶部的对象。
  3. peek():

    • 此方法用于查看此栈顶部的对象,但不从栈中移除它。
    • 如果此栈为空,则抛出EmptyStackException
    • 返回值:栈顶部的对象。
  4. empty():

    • 此方法用于测试此栈是否为空。
    • 如果栈不包含任何元素,则返回true;否则返回false
  5. search(Object o):

    • 此方法返回对象在栈中的位置,以1为基数。
    • 如果此对象不在栈中,则返回-1。
  6. clear():

    • 从栈中移除所有元素。
    • 此方法继承自Vector类。
  7. size():

    • 返回栈中的元素数量。
    • 此方法也继承自Vector类。

重点关注Stack类javadoc中的这句:

需要注意的是,虽然java.util.Stack类提供了这些方便的方法,但在现代的Java编程实践中,通常更推荐使用Deque接口的实现类(如ArrayDeque)来实现堆栈的功能,因为Deque提供了更完整、更灵活的堆栈操作,并且通常具有更好的性能。

此外,当使用堆栈时,应注意处理可能出现的EmptyStackException,特别是在调用pop()peek()方法时,应确保堆栈不为空。

最后,再回来看看Deque,用Deque中的javadoc注解看看它提供的与Queue以及与Stack等价的方法,如下:

可见,其不论是作为队列使用还是作为堆栈使用,都有完整的操作支持。

接下来,就是它们的实现类中不断学习和研究吧~~~

  • 29
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java.util包是Java标准库中的一个核心包,提供了许多常用的工具类和数据结构。下面是一些java.util包中的例子: 1. ArrayList:动态数组,可以随时添加或删除元素。 ```java import java.util.ArrayList; public class ArrayListExample { public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); list.add("apple"); list.add("banana"); list.add("orange"); for (String fruit : list) { System.out.println(fruit); } } } ``` 2. HashMap:哈希表,以键值对的形式存储数据。 ```java import java.util.HashMap; public class HashMapExample { public static void main(String[] args) { HashMap<String, Integer> map = new HashMap<String, Integer>(); map.put("apple", 1); map.put("banana", 2); map.put("orange", 3); System.out.println(map.get("apple")); } } ``` 3. HashSet:哈希集合,存储不重复的元素。 ```java import java.util.HashSet; public class HashSetExample { public static void main(String[] args) { HashSet<String> set = new HashSet<String>(); set.add("apple"); set.add("banana"); set.add("orange"); System.out.println(set.contains("apple")); } } ``` 4. LinkedList:双向链表,可以在任意位置添加或删除元素。 ```java import java.util.LinkedList; public class LinkedListExample { public static void main(String[] args) { LinkedList<String> list = new LinkedList<String>(); list.add("apple"); list.add("banana"); list.add("orange"); System.out.println(list.getFirst()); } } ``` 以上只是java.util包中的一小部分,还有许多其他有用的类和数据结构,可以根据需求选择使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值