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日

相关文章

  • Spring 使用注解方式进行事务管理配置方式

    Spring 使用注解方式进行事务管理的配置方式主要是通过在类或方法上添加@Transactional注解来进行配置。下面是完整的配置流程: 引入相关依赖 Spring 支持多种事务管理方式,而使用注解方式进行事务管理需要引入如下依赖: <!– Spring JDBC –> <dependency> <groupId>…

    Java 2023年5月20日
    00
  • Java编程实现统计一个字符串中各个字符出现次数的方法

    下面是实现统计一个字符串中各个字符出现次数的攻略。 步骤一:定义Map对象 在Java中,我们可以使用Map对象来统计每个字符出现的次数。首先需要定义一个Map对象,键是字符,值是该字符出现的次数。Map对象的实例化可以用以下代码: Map<Character, Integer> charCountMap = new HashMap<Cha…

    Java 2023年5月27日
    00
  • Java中MyBatis Plus知识点总结

    下面我针对“Java中MyBatis Plus知识点总结”的完整攻略逐步讲解。 MyBatis Plus是什么? MyBatis Plus 是一款 MyBatis 增强工具,简化了 MyBatis 的使用流程,提供了很多实用的增强功能。相比 MyBatis,使用 MyBatis Plus 能够更加高效地进行数据持久化操作。 MyBatis Plus主要功能 …

    Java 2023年5月20日
    00
  • maven 在执行package,install,deploy时使用clean与不使用clean的不同之处

    Maven 是一种流行的项目管理工具,它以项目对象模型 (POM) 为基础,提供了一种标准化的方式来构建和管理项目。在执行 Maven 中的几个主要操作时,包括 package、install、deploy 等,我们可以使用 clean 来清理之前编译的产物,或者不使用 clean 来直接构建产物。使用或者不使用 clean 的主要区别在于编译产物是否被清理…

    Java 2023年5月19日
    00
  • 20基于java的科研管理系统设计与实现

    背景及意义 目前许多人仍将传统的纸质工具作为信息管理的主要工具,而网络技术的应用只是起到辅助作用。在对网络工具的认知程度上,较为传统的office软件等仍是人们使用的主要工具,而相对全面且专业的信息管理软件仍没有得到大多数人的了解或认可。本选题则旨在通过标签分类管理等方式,实现教研的各种功能,从而达到对科研管理系统的管理。 科研项目管理系统,以项目化管理为思…

    Java 2023年5月4日
    00
  • java实战小技巧之优雅的实现字符串拼接

    下面是关于”Java实战小技巧之优雅的实现字符串拼接”的攻略。 背景 字符串拼接是Java开发中比较基础的操作之一,但是在不注意的情况下,随意的字符串拼接方式可能会导致代码的可读性和可维护性下降。因此,在进行Java开发时,需要注意如何优雅地实现字符串拼接,提高代码的可读性、可维护性和效率。 方式一:使用StringBuilder 在Java中,字符串拼接的…

    Java 2023年5月26日
    00
  • React Native JSI实现RN与原生通信的示例代码

    React Native JSI 是 React Native 的一个新特性,它可以实现 RN 与原生端的通信。JSI 基于 C++,所以可以很好地利用移动设备的 CPU 和 GPU 功能,从而提高应用程序的性能和可维护性。 要使用 RN JSI,需要在项目中安装相应的模块和库,例如 Folly 和 TurboModules。接下来,我们将详细讲解如何在 R…

    Java 2023年6月15日
    00
  • Java ArrayList 数组之间相互转换

    下面是Java ArrayList数组之间相互转换的完整攻略。 ArrayList 和数组之间的区别 在Java中,ArrayList和数组都可以用来存储多个相同类型的元素。但是,它们有以下的区别: 数组是静态数据类型,需要预先指定长度,而且只能存储同一种类型的元素; ArrayList则是动态数据类型,可以在不确定元素个数的情况下存储多个不同类型的元素,并…

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