Java源码刨析之ArrayDeque

Java源码刨析之ArrayDeque

Java中的ArrayDeque是一种基于动态数组的双端队列数据结构。本篇文章将与读者一起深入分析Java中ArrayDeque的源代码,从中学习这种数据结构的实现原理。

容量扩充

由于使用动态数组来存储队列中的元素,因此在添加元素时,需要判断是否需要扩展数组的容量。容量扩充的代码实现如下:

private void doubleCapacity() {
    int newCapacity = elements.length << 1;
    if (newCapacity < 0)
        throw new IllegalStateException("Sorry, deque too big");
    Object[] newArray = new Object[newCapacity];
    int headN = elements.length - head;
    System.arraycopy(elements, head, newArray, 0, headN);
    System.arraycopy(elements, 0, newArray, headN, head);
    elements = newArray;
    head = 0;
    tail = size;
}

这段代码中首先将数组容量扩展为原来的两倍,然后使用System类的arraycopy()方法将原数组中从head位置开始到末尾的元素拷贝到新的数组的开头,将原数组中从0位置到head位置的元素拷贝到新的数组中从headN位置开始的位置,最后再改变head和tail的值,以确定队列的范围和队列大小。

入队操作

队列的入队操作代码如下:

public boolean add(E e) {
    addLast(e);
    return true;
}

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

这段代码首先将新元素添加到队列的尾部,并通过位运算的方式取得新的tail值。然后检查队列是否已满,如果满了就执行容量扩充操作。

出队操作

队列的出队操作代码如下:

public E removeFirst() {
    E x = pollFirst();
    if (x == null)
        throw new NoSuchElementException();
    return x;
}

public E pollFirst() {
    int h = head;
    @SuppressWarnings("unchecked")
    E result = (E) elements[h];
    // Element is null if deque empty
    if (result == null)
        return null;
    elements[h] = null;     // Must null out slot
    head = (h + 1) & (elements.length - 1);
    size--;
    return result;
}

这段代码首先调用了pollFirst()方法获取队列中第一个元素,并返回该元素的值。如果该元素为null,则抛出NoSuchElementException异常。最后还需要将head的值加1,并将队列大小减1。

示例说明

下面以两条示例说明ArrayDeque的使用。

示例1:正向遍历

ArrayDeque<String> deque = new ArrayDeque<>();
deque.add("Java");
deque.add("is");
deque.add("awesome");

for(String str : deque) {
    System.out.println(str);
}

输出结果:
Java
is
awesome

该示例首先创建了一个String类型的ArrayDeque对象,在该对象中添加了三个元素。然后使用for循环遍历该队列,依次打印出队列中的每个元素。

示例2:反向遍历

ArrayDeque<String> deque = new ArrayDeque<>();
deque.push("Java");
deque.push("is");
deque.push("awesome");

Iterator<String> iterator = deque.descendingIterator();

while(iterator.hasNext()) {
    System.out.println(iterator.next());
}

输出结果:
awesome
is
Java

该示例与示例1类似,创建了一个String类型的ArrayDeque对象,并在该对象中添加了三个元素。不同之处在于使用push()方法将元素添加到队列的头部。接着使用迭代器将队列反向遍历,并依次打印出所有元素。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java源码刨析之ArrayDeque - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • SpringBoot使用JdbcTemplate访问操作数据库基本用法

    SpringBoot使用JdbcTemplate访问操作数据库基本用法 简介 JdbcTemplate 是 Spring 框架提供的一种基于 JDBC 的访问数据库的工具,使用它可以简化 JDBC 的开发流程和操作,减少大量模板式代码的编写。结合 SpringBoot 使用 JdbcTemplate 可以更加方便地访问和操作数据库。 Maven 依赖 在 S…

    Java 2023年5月20日
    00
  • JDBC数据库连接步骤解析

    JDBC是Java Database Connectivity的缩写,用于Java语言访问关系型数据库的API。下面就来详细讲解JDBC数据库连接步骤解析。 JDBC数据库连接步骤 加载数据库驱动:通过Class.forName()方法加载数据库驱动,例如加载mysql数据库驱动可以使用以下代码: Class.forName(“com.mysql.jdbc.…

    Java 2023年5月20日
    00
  • 一小时迅速入门Mybatis之bind与多数据源支持 Java API

    下面是关于“一小时迅速入门 Mybatis 之 bind 与多数据源支持 Java API”的完整攻略: 什么是 Mybatis Mybatis 是一款优秀的 Java ORM 框架,它的主要作用是将数据库表映射成 Java 对象。在 Mybatis 中,可以通过 XML 或 Java 注解的方式进行数据映射,同时提供了丰富的 SQL 语句拼接、缓存、事务控…

    Java 2023年5月20日
    00
  • SpringBoot实现物品点赞功能

    下面是关于SpringBoot实现物品点赞功能的完整攻略: 前言 物品点赞功能是很常见的网站功能之一。Spring Boot 给我们提供了很好的实现方式,通过本文,你可以学习到 Spring Boot 如何实现物品点赞功能。 实现过程 创建数据库 首先我们需要创建一个数据库来储存点赞信息。数据库需要包含以下两个表: item 表:储存物品信息,包括物品 ID…

    Java 2023年5月23日
    00
  • 什么是线程状态?

    以下是关于线程状态的完整使用攻略: 什么是线程状态? 线程状态是指线程在不同的执行阶段处的状态。在 Java 中,线程状态主要有以下几种: 新建状态(New):当线程对象被创建时,它处于新建状态。 就状态(Runnable):当线程对象调用 start() 方法后,它处于就绪状态,等待系统分配 CPU 时间片。 运行状态():当线程获得 CPU 时间片后,它…

    Java 2023年5月12日
    00
  • 一篇文章带你学习JAVA MyBatis底层原理

    一篇文章带你学习JAVA MyBatis底层原理 MyBatis是一个基于Java的ORM框架,它可以将数据库记录映射成对象,屏蔽了大部分的JDBC操作。文章将带你深入了解MyBatis底层原理。我们将分以下四个部分:解析MyBatis类结构、解析MyBatis配置文件、解析Mapper映射文件、MyBatis执行流程。 解析MyBatis类结构 MyBat…

    Java 2023年5月20日
    00
  • 详解MybatisPlus集成nacos导致druid连接不上数据库

    我很高兴为您提供“详解MybatisPlus集成nacos导致druid连接不上数据库”的完整攻略。 问题描述MybatisPlus集成nacos后,我们发现druid连接池无法连接数据库了,导致应用程序无法启动。这是由于Druid数据源在生成时需要使用一些配置参数,例如驱动类名、连接字符串、用户名/密码等,而这些参数在nacos配置中心中没有被正确指定。 …

    Java 2023年6月15日
    00
  • Java 如何解决跨域问题

    Java 如何解决跨域问题 跨域问题是指在浏览器中,当一个网页的脚本试图访问另一个网页的脚本时,由于浏览器的同源策略,会被拒绝访问。Java Web应用程序可以通过以下几种方式来解决跨域问题。 1. CORS(跨域资源共享) CORS是一种机制,允许Web应用程序从不同的域访问其资源。CORS通过在响应头中添加Access-Control-Allow-Ori…

    Java 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部