百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

Java Deque操作指南(java defaut)

ztj100 2025-03-20 21:19 47 浏览 0 评论

由于前文《一文讲透LinkedList》对Deque的具体使用并未详写,因此在此处补上。前文已讲明Java 集合类的关系图,因此不在此再次说明。

介绍

Deque是java.util包中Queue接口的子类型,Deque是“双端队列”,支持从数据结构的任何一端添加或删除数据。它既可以用作队列(FIFO/先进先出),也可以用作栈(LIFO/后进先出)。

接口声明:

public interface Deque extends Queue {
    /**
     * 将指定的元素插入此双端队列的前面 ,空间不足抛异常
     */
    void addFirst(E e);

    /**
     * 将指定的元素插入此双端队列的后面 ,空间不足抛异常
     */
    void addLast(E e);

    /**
     * 将指定的元素插入此双端队列的前面 ,空间不足返回false
     */
    boolean offerFirst(E e);

    /**
     * 将指定的元素插入此双端队列的后面,空间不足返回false
     */
    boolean offerLast(E e);

    /**
     * 检索并删除第一个元素,deque为空时抛出异常
     */
    E removeFirst();

    /**
     * 检索并删除最后一个元素,deque为空时抛出异常
     */
    E removeLast();

    /**
     * 检索并删除第一个元素 ,deque为空时返回null
     */
    E pollFirst();

    /**
     * 检索并删除最后一个元素 ,deque为空时返回null
     */
    E pollLast();

    /**
     * 检索第一个元素 ,不从队列中删除,deque为空就抛异常
     */
    E getFirst();

    /**
     * 检索最后一个元素 ,不从队列中删除,deque为空就抛异常
     */
    E getLast();

    /**
     * 检索第一个元素 ,不从队列中删除,deque为空就则返回null
     */
    E peekFirst();

    /**
     * 检索最后一个元素 ,不从队列中删除,deque为空就则返回null
     */
    E peekLast();

    /**
     * 删除deque中第一个出现的元素,如果元素存在,则返回true
     */
    boolean removeFirstOccurrence(Object o);

    /**
     * 删除deque中最后一个出现的元素,如果元素存在,则返回true
     */
    boolean removeLastOccurrence(Object o);

    // *** 此部分为Queue接口的方法定义 ***

    /**
     * 将指定的元素插入此双端队列的后面,空间不足抛异常
     */
    boolean add(E e);

    /**
     * 将指定的元素插入此双端队列的后面,空间不足返回false
     */
    boolean offer(E e);

    /**
     * 和removeFirst一样 检索并删除第一个元素,为空时抛出异常
     */
    E remove();

    /**
     * 和pollFirst一样 检索并删除第一个元素 ,为空时返回null
     */
    E poll();

    /**
     * 和getFirst一样 只查看第一个元素 ,不从队列中删除,为空就抛异常
     */
    E element();

    /**
     * 和peekFirst一样 只查看第一个元素 ,不从队列中删除,为空时返回null
     */
    E peek();


    // *** 此部分为Stack接口的方法 ***

    /**
     * 将指定的元素插入此双端队列的前面 ,空间不足抛异常
     */
    void push(E e);

    /**
     * 和removeFirst一样,检索并删除第一个元素,为空时抛出异常
     */
    E pop();


    // *** 此部分为Collection接口的方法 ***

    /**
     * 和removeFirstOccurrence一样,删除deque中第一个出现的元素,
     * 如果元素存在,则返回true
     */
    boolean remove(Object o);

    /**
     * 如果deque中包含指定的元素,那么返回true,否则返回false
     */
    boolean contains(Object o);

    /**
     * 返回deque中的元素个数
     */
    public int size();

    /**
     * 按适当的顺序返回deque容器中所有元素的迭代器。
     * 元素将按照从头部到尾部的顺序返回。
     */
    Iterator iterator();

    /**
     * 返回一个迭代器,对deque容器中的元素按相反的顺序进行迭代。
     * 元素将按照从尾部到头部的顺序返回。
     */
    Iterator descendingIterator();

}

创建Deque对象

// 方式一:使用ArrayDeque创建
Deque deque = new ArrayDeque<>();

// 方式二:使用LinkedList创建
Deque deque = new LinkedList<>();

添加元素

要在双端队列中添加元素,我们可以使用add()方法。队列和双端队列的区别在于,在双端队列中,可以从两端进行添加元素。从头部添加元素的方法为:addFirst(),从尾部添加元素的方法为addLast()

Deque deque = new ArrayDeque<>();

deque.add(1); // 添加到尾部
deque.addFirst(2); // 添加到头部
deque.addLast(3); // 添加到尾部

System.out.println(deque); // 输出 [2, 1, 3]

移除元素

要在双端队列中移除元素,我们可以使用removeFirst()、removeLast()方法。除此之外,还可以使用 poll()、pop()、pollFirst()、pollLast() 方法。其中 pop() 用于移除和返回双端队列的头部。

注意:poll() 提供了与 pop() 相同的功能,区别在于 poll() 在双端队列为空时不会返回异常。

示例:

Deque deque = new ArrayDeque<>();

deque.add(1);
deque.addFirst(2);
deque.addLast(3);

System.out.println(deque);
System.out.println(deque.pop());
System.out.println(deque.poll());
System.out.println(deque.pollFirst());
System.out.println(deque.pollLast());

输出:
[2, 1, 3]
2
1
3
null

Deque遍历

Deque可以从两个方向进行遍历,如下:

Deque deque = new ArrayDeque<>();

deque.add(1);
deque.addFirst(2);
deque.addLast(3);

// 正向遍历,输出: 2 1 3 
Iterator iter = deque.iterator();
while (iter.hasNext()) {
    System.out.print(iter.next() + " ");
}

// 反向遍历,输出:3 1 2 
Iterator desIter = deque.descendingIterator();
while (desIter.hasNext()) {
    System.out.print(desIter.next() + " ");
}

常见问题

Q #1) Deque 是线程安全的吗?

答: ArrayDeque/LinkedList 不是线程安全的。但是 java.util.concurrent 包中的 BlockingDeque 是线程安全的。

Q #2)为什么 Deque 比 stack 快?

答:常用的 Deque 的 ArrayDeque 实现是内存高效的,它不需要跟踪前一个或下一个节点。此外,它是一个可调整大小的实现。因此双端队列比堆栈快。

Q #3) Deque 是堆栈吗?

答:Deque 是双端队列。它允许 LIFO(后进先出)行为,因此它可以作为一个堆栈来实现,但它不是一个堆栈。

Q #4) Deque 在哪里使用?

答:双端队列主要用于实现撤销和历史等功能。比如排队购票系统,对排队者的存储可以采用deque,支持头端的快速移除,尾端的快速添加。或者也可以使用deque实现一个浏览器的返回栈。

Q #5) ArrayDeque 和 LinkedList 比较

答:如果只需要Deque接口,只从两端进行元素操作,一般而言,ArrayDeque效率更高一些,应该被优先使用。不过,如果同时需要根据索引位置进行操作,或者经常需要在中间进行插入和删除,则应该选LinkedList(注意,这里使用的是List特性,而不是Deque特性了)。

相关推荐

其实TensorFlow真的很水无非就这30篇熬夜练

好的!以下是TensorFlow需要掌握的核心内容,用列表形式呈现,简洁清晰(含表情符号,<300字):1.基础概念与环境TensorFlow架构(计算图、会话->EagerE...

交叉验证和超参数调整:如何优化你的机器学习模型

准确预测Fitbit的睡眠得分在本文的前两部分中,我获取了Fitbit的睡眠数据并对其进行预处理,将这些数据分为训练集、验证集和测试集,除此之外,我还训练了三种不同的机器学习模型并比较了它们的性能。在...

机器学习交叉验证全指南:原理、类型与实战技巧

机器学习模型常常需要大量数据,但它们如何与实时新数据协同工作也同样关键。交叉验证是一种通过将数据集分成若干部分、在部分数据上训练模型、在其余数据上测试模型的方法,用来检验模型的表现。这有助于发现过拟合...

深度学习中的类别激活热图可视化

作者:ValentinaAlto编译:ronghuaiyang导读使用Keras实现图像分类中的激活热图的可视化,帮助更有针对性...

超强,必会的机器学习评估指标

大侠幸会,在下全网同名[算法金]0基础转AI上岸,多个算法赛Top[日更万日,让更多人享受智能乐趣]构建机器学习模型的关键步骤是检查其性能,这是通过使用验证指标来完成的。选择正确的验证指...

机器学习入门教程-第六课:监督学习与非监督学习

1.回顾与引入上节课我们谈到了机器学习的一些实战技巧,比如如何处理数据、选择模型以及调整参数。今天,我们将更深入地探讨机器学习的两大类:监督学习和非监督学习。2.监督学习监督学习就像是有老师的教学...

Python教程(三十八):机器学习基础

...

Python 模型部署不用愁!容器化实战,5 分钟搞定环境配置

你是不是也遇到过这种糟心事:花了好几天训练出的Python模型,在自己电脑上跑得顺顺当当,一放到服务器就各种报错。要么是Python版本不对,要么是依赖库冲突,折腾半天还是用不了。别再喊“我...

超全面讲透一个算法模型,高斯核!!

...

神经网络与传统统计方法的简单对比

传统的统计方法如...

AI 基础知识从0.1到0.2——用“房价预测”入门机器学习全流程

...

自回归滞后模型进行多变量时间序列预测

下图显示了关于不同类型葡萄酒销量的月度多元时间序列。每种葡萄酒类型都是时间序列中的一个变量。假设要预测其中一个变量。比如,sparklingwine。如何建立一个模型来进行预测呢?一种常见的方...

苹果AI策略:慢哲学——科技行业的“长期主义”试金石

苹果AI策略的深度原创分析,结合技术伦理、商业逻辑与行业博弈,揭示其“慢哲学”背后的战略智慧:一、反常之举:AI狂潮中的“逆行者”当科技巨头深陷AI军备竞赛,苹果的克制显得格格不入:功能延期:App...

时间序列预测全攻略,6大模型代码实操

如果你对数据分析感兴趣,希望学习更多的方法论,希望听听经验分享,欢迎移步宝藏公众号...

AI 基础知识从 0.4 到 0.5—— 计算机视觉之光 CNN

...

取消回复欢迎 发表评论: