学习一下Java的ArrayList和contains函数和扩容机制

这篇具有很好参考价值的文章主要介绍了学习一下Java的ArrayList和contains函数和扩容机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

起因

在Leetcode上做题写了两种暴力解法,但是执行效率上不太一样。
学习一下Java的ArrayList和contains函数和扩容机制

时间上差很远,内存虽然差不多但是前者击败30%,后者击败94%。这两种解法区别是用一条ArrayList还是两条来存数据,所以contains虽然执行次数一样但是检测的长度上不一样,而且ArrayList的扩容次数也不一样,所以学习一下。

contains(Object o)

直接翻(JDK8)源码:
学习一下Java的ArrayList和contains函数和扩容机制
nullobject区分开来还是因为equals有一方是null的话都会导致异常. 合并一起写的话可以用Objects.equals(obj1, obj2)的写法.
所以显然暴力解法用到的contains原理就是朴实无华的一遍遍搜索所以时间特别长.

ArrayList扩容机制

省流: 直接看最下面的grow函数.

如果是默认的ArrayList, 添加元素时会先计算数组长度, 如果元素个数+1大于当前数组长度+1大于elementData.length时进行扩容,扩容后的数组大小是: oldCapacity + (oldCapacity >> 1) ,位运算右移1位表示除以2, 所以可以理解成1.5倍扩容。

涉及到的源码:

// 向指定索引位置插入元素
public void add(int index, E element) {
    // 检查索引范围
    rangeCheckForAdd(index);

    // 确保容量足够
    ensureCapacityInternal(size + 1);  // 增加 modCount(用于支持并发修改的计数器)
    // 使用 System.arraycopy 将元素后移,为新元素腾出位置, 这是跟另一个add的区别⭐⭐⭐⭐⭐
    System.arraycopy(elementData, index, elementData, index + 1, size - index);
    elementData[index] = element; // 在指定位置插入新元素
    size++; // 更新列表大小
}

// 在列表末尾添加元素
public boolean add(E e) {
    // 确保容量足够
    ensureCapacityInternal(size + 1);  // 增加 modCount
    elementData[size++] = e; // 在列表末尾添加新元素
    return true;
}

// 内部方法:确保容量足够
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

// 内部方法:计算容量
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        // 如果内部数组为空,返回默认容量或所需容量中的较大者
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity; // 否则返回所需容量
}

// 内部方法:确保容量足够
private void ensureExplicitCapacity(int minCapacity) {
    modCount++; // 增加并发修改计数器

    // 检查容量是否足够,如果不够则扩展
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

// 内部方法:扩展容量
private void grow(int minCapacity) {
    // 溢出安全的代码
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量通常为旧容量的1.5倍
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity; // 如果新容量小于所需容量,使用所需容量
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity); // 处理可能的巨大容量情况
    // 使用 Arrays.copyOf 扩展数组容量
    elementData = Arrays.copyOf(elementData, newCapacity);
}


实际上Array.copyof底层调用的还是System.arraycopy.文章来源地址https://www.toymoban.com/news/detail-711403.html

到了这里,关于学习一下Java的ArrayList和contains函数和扩容机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 源码分析——ArrayList源码+扩容机制分析

    ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用 ensureCapacity 操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。 ArrayList 继承于 AbstractList ,实现了 List , RandomAccess , Cloneable , ja

    2024年02月14日
    浏览(35)
  • 【Java集合类面试二十六】、介绍一下ArrayList的数据结构?

    文章底部有个人公众号: 热爱技术的小郑 。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官:介绍一下ArrayList的数据结构? 参考答案: ArrayList的底

    2024年02月08日
    浏览(33)
  • 深入源码解析ArrayList:探秘Java动态数组的机制与性能

    1.1 介绍ArrayList的基本概念和作用 在Java中,ArrayList是一个实现了List接口的动态数组。它可以根据需要自动增加大小,因此可以存储任意数量的元素。 基本概念: ArrayList是Java中常用的集合类之一,它可以存储对象,并且可以根据索引访问和操作这些对象。 ArrayList是基于数组

    2024年02月04日
    浏览(31)
  • ArrayList是如何动态扩容的

    ArrayList是Java中常用的动态数组实现,在底层是使用数组来存储元素。当需要扩展ArrayList的长度时,它会执行以下步骤: 初始化数组:在创建ArrayList对象时,会初始化一个初始长度的数组来存储元素。默认情况下,初始长度为10。 添加元素时的扩容:当往ArrayList中添加元素时

    2024年02月15日
    浏览(27)
  • java学习——ArrayList和泛型(学习记录)

    学习资料来自菜鸟教程 ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。 ArrayList 继承了 AbstractList ,并实现了 List 接口。 ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下: E: 泛型数据类型,

    2024年02月06日
    浏览(52)
  • 关于函数宏offset_of 和 container_of的学习

    用途: 用于获取获取结构体某一个成员在该结构体中的位置 参数1: type ,表示结构体的类型 参数2: member  表示结构体成员 分析: (unsigned int)   (type*)0)-member   a.把值为0的指针强制转换成该结构体类型 b.通过该指针找到该成员     c.获取该成员相对于0 的地址偏移 d.强转

    2024年02月05日
    浏览(34)
  • 云盘满了怎么办?阿里云服务器云盘扩容操作了解一下

         1.背景      2.确定扩容云盘类型与控制台操作      3.ECS实例内部扩容操作说明          3.1 ECS实例内部执行扩容分区          3.2 ECS实例内部执行扩容文件系统      软件应用的数据库所在服务器磁盘使用率已经达到97%,服务器操作实例如下:      一旦使用

    2024年02月08日
    浏览(46)
  • ArrayList快速失败机制

    ArrayList实现了一种称为 快速失败 (fail-fast)的机制,该机制在并发修改时会抛出 ConcurrentModificationException 异常。 这种机制的实现原理是:ArrayList在遍历时会 记录列表的修改总数 (通过modCount字段),如果在遍历过程中列表结构发生变化,那么modCount的值会增大。 每次遍历前,迭代器都会

    2024年02月04日
    浏览(21)
  • 【JAVA学习笔记】53 - 集合-List类及其子类Collection、ArrayList、LinkedList类

    https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter14/src/com/yinhai/collection_ https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter14/src/com/yinhai/list_ 目录 项目代码 集合 一、引入 数组 集合 二、集合的框架体系 单列集合        双列集合        Collection类 一、Collection类接

    2024年02月06日
    浏览(47)
  • vector扩容机制

    在学习了vector的时候,总说linux下是以二倍扩容的,VS是以1.5倍扩容的。 但是想一想为什么扩容是这样的呢,为什么不能是3倍或者其他倍数呢?  所以带着这些疑问,接着往下看。 首先,我们要知道vector的扩容机制:当向vector插入元素的时候,即当_finish == _end_of_storage,可能

    2024年01月15日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包