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

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

null和object区分开来还是因为equals有一方是null的话都会导致异常. 合并一起写的话可以用Objects.equals(obj1, obj2)的写法.
所以显然暴力解法用到的contains的原理就是朴实无华的一遍遍搜索所以时间特别长.
ArrayList扩容机制
省流: 直接看最下面的grow函数.
如果是默认的ArrayList, 添加元素时会先计算数组长度, 如果元素个数+1大于当前数组长度+1大于elementData.length时进行扩容,扩容后的数组大小是: oldCapacity + (oldCapacity >> 1) 可以理解成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.
学习一下Java的ArrayList和contains函数和扩容机制的更多相关文章
- 浅谈JAVA中HashMap、ArrayList、StringBuilder等的扩容机制
JAVA中的部分需要扩容的内容总结如下:第一部分: HashMap<String, String> hmap=new HashMap<>(); HashSet<Strin ...
- [java学习笔记]java语言基础概述之函数的定义和使用&函数传值问题
1.函数 1.什么是函数? 定义在类中的具有特定功能的一段独立小程序. 函数也叫做方法 2.函数的格式 修饰符 返回值类型 函数名(参数类型 形式参数1, 参数类型 形式参数2-) { ...
- [学习笔记]Java代码中各种类型变量的内存分配机制
程序运行时,我们最好对数据保存到什么地方做到心中有数.特别要注意的是内存的分配.有六个地方都可以保存数据: (1) 寄存器 这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部.然而 ...
- 大数据学习笔记——Java篇之集合框架(ArrayList)
Java集合框架学习笔记 1. Java集合框架中各接口或子类的继承以及实现关系图: 2. 数组和集合类的区别整理: 数组: 1. 长度是固定的 2. 既可以存放基本数据类型又可以存放引用数据类型 3 ...
- $.ajax函数调接口,报异常No converter found for return value of type: class java.util.ArrayList
接口正常执行,返回给前端后报服务器500异常,异常详情: org.springframework.http.converter.HttpMessageNotWritableException: No ...
- java学习笔记之集合—ArrayList源码解析
1.ArrayList简介 ArrayList是一个数组队列,与java中的数组的容量固定不同,它可以动态的实现容量的增涨.所以ArrayList也叫动态数组.当我们知道有多少个数据元素的时候,我们用 ...
- java学习笔记20(Arraylist复习,Collection接口方法,迭代器,增强型for循环)
集合:集合是Java提供的一种容器,可以用来存储多个数据: 集合与数组的区别:集合的长度是可变的,数组的长度是固定的 集合中存储的数据必须是引用类型数据: ArrayList回顾: public cl ...
- Java集合---ArrayList的实现原理
目录: 一. ArrayList概述 二. ArrayList的实现 1) 私有属性 2) 构造方法 3) 元素存储 4) 元素读取 5) 元素删除 6) 调整数组容量 ...
- 一篇很好的学习查看Java源代码的文章
目录: 一. ArrayList概述 二. ArrayList的实现 1) 私有属性 2) 构造方法 3) 元素存储 4) 元素读取 5) 元素删除 6) 调整数组容量 ...
- JAVA中ArrayList用法
JAVA中ArrayList用法 2011-07-20 15:02:03| 分类: 计算机专业 | 标签:java arraylist用法 |举报|字号 订阅 Java学习过程中做题时 ...
随机推荐
- GO网络编程(二)
[[Go语言系列视频]老男孩带你21周搞定Go语言[全 242]] https://www.bilibili.com/video/BV1fD4y117Dg/?p=113&share_sourc ...
- 一行命令使用 Docker 编译 Latex 文件,简单优雅
使用 Docker 编译 LaTeX 文章 LaTeX 是一种常用的排版系统,它可以帮助用户创建漂亮.专业的文档.但是,安装和配置 LaTeX 比较麻烦,特别是对于初学者而言. Docker 是一个开 ...
- GetX 关于报错 Null check operator used on a null value的解决
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'logic.dart'; class Ge ...
- 在VS Code 中调试远程服务器的PHP代码
背景 对于PHP的调试,一般来说我们用 echo 和 var_dump 就够用了. 有时会碰到要解决复杂的逻辑或需要确认代码的运行顺序,这里用var_dump效率就比较低了,这时建议用断点的方式进行代 ...
- 【调制解调】PM 调相
说明 学习数字信号处理算法时整理的学习笔记.同系列文章目录可见 <DSP 学习之路>目录,代码已上传到 Github - ModulationAndDemodulation.本篇介绍 PM ...
- gin 接口开发 - 用户输入自动 TrimSpace
最近在思考一个问题,针对用户的输入,能不能快速校验? 比方说下面的 struct,大家用过 gin 的就知道,支持指定某个字段为 required,用户如果不输入,就检验不通过. type Login ...
- NOIP模拟测试A3
A. 谜之阶乘 题目是让我们把 \(n\) 分解成两个阶乘的商,本来想推个式子什么的,结果发现推不出来. 我们知道,阶乘的增长速率非常的快啊!那么这个 \(b - a\) 的值肯定不会太大,我们可以暴 ...
- Cilium系列-1-Cilium特色 功能及适用场景
系列文章 Cilium 系列文章 Cilium 简介 Cilium 是一个开源的云原生解决方案,用于提供.保护(安全功能)和观察(监控功能)工作负载之间的网络连接,由革命性的内核技术 eBPF 提供动 ...
- MAUI中Windows的标题栏颜色怎么设置
如下图所示,MAUI中Windows下的标题栏是灰色的,如何设置颜色,找了很久,在GitHub上的issue中找到了答案, 找到/Platforms/Windows/App.xaml <maui ...
- Java与PHP的区别
1.PHP暂时不支持像Java那样的JIT运行时编译的热点代码,但PHP具有opcache机制,能够将脚本对应的opcode缓存在内存中. 补充:JIT与JVM的三种执行模式:解释模式.编译模式.混合 ...