Java|ArrayList源码分析|add()增加方法和grow()扩容方法
本文结构:
1.介绍特点
2.基本方法
3.重点源码分析
1.介绍特点
ArrayList:
是List的一个具体实现子类,是List接口的一个数组实现 (里面必定维护了一个数组)。
默认初始容量10, 扩容机制1.5倍。(数组必然有初始容量和扩容机制)
有序。
允许null元素。
允许重复元素。
线程不安全。
2.基本方法
| 关键字 | 简介 |
|---|---|
add |
增加 |
contains |
判断是否存在 |
get |
获取指定位置的对象 |
indexOf |
获取对象所处的位置 |
remove |
删除 |
set |
替换 |
size |
获取大小 |
toArray |
转换为数组 |
addAll |
把另一个容器所有对象都加进来 |
clear |
清空 |
3.重点源码分析
源码解析:
public class MyArrayList<E>{
private static final int DEFAULT_CAPACITY = 10;// 默认容量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;// 最大容量
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA ={} ;//空数组
private Object[] elements;//底层维护的数组
private int size;//容器内对象的个数
private int modCount;//记录ArrayList这个对象被修改的次数
//构造方法
public MyArrayList(Object[] elements) {
this.elements = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
*增加内容
* @param e
* @return
*/
public boolean add(E e) {
//创建一个默认为10的数组,若小则扩容
int minCapacity=size+1;
ensureCapacityInternal(minCapacity);
//确保容量够,则添加数据,并讲数据大小加1.
elements[size]=e;
size++;
return true;
}
//该方法来确保数组的容量够用,若为创建则创建数组并赋予默认值。
private void ensureCapacityInternal(int minCapacity) {
//若数组为空(还未添加数据)
if (elements==DEFAULTCAPACITY_EMPTY_ELEMENTDATA){
//则选出默认值和最小容量的最大值
minCapacity=Math.max(DEFAULT_CAPACITY,minCapacity);
//只add方法其实没必要比较,主要是addAll()这个方法需要比较
}
modCount++;//修改次数加一
//判断一下是否需要扩容,若数据+1大于当前数组,则需要扩容
if(minCapacity-elements.length>0){
grow(minCapacity);//调用扩容方法
}
}
//扩容具体方法
private void grow(int minCapacity){
int oldCapacity=elements.length;//获取原始数组的长度
int newCapacity=oldCapacity+(oldCapacity>>1);//扩容 1+0.5 倍
//若扩容后的长度比所需要的最低长度还要小,则直接把扩容的长度更改为最低所需长度
if (newCapacity-minCapacity<0){
newCapacity=minCapacity;
}
//若扩容完的新长度比规定的最大容量还大,则要进一步判断,并进一步修改数组大小
if (newCapacity-MAX_ARRAY_SIZE>0){
//若所需的容量竟然小于0,说明超过Int最大值,越界了,抛出异常
if (minCapacity<0){
throw new OutOfMemoryError();
}
//若所需的容量不超过Int最大值,则再判断
if (minCapacity>MAX_ARRAY_SIZE){//若所需的大于数组要求的而小于Int最大值
newCapacity=Integer.MAX_VALUE;//直接赋值Int最大值
}else{//否则只有小于数组最大值这一种情况了,赋予数组最大值即可
newCapacity=MAX_ARRAY_SIZE;
}
}
}
}
Java|ArrayList源码分析|add()增加方法和grow()扩容方法的更多相关文章
- Java ArrayList源码分析(有助于理解数据结构)
arraylist源码分析 1.数组介绍 数组是数据结构中很基本的结构,很多编程语言都内置数组,类似于数据结构中的线性表 在java中当创建数组时会在内存中划分出一块连续的内存,然后当有数据进入的时候 ...
- Java ArrayList源码分析(含扩容机制等重点问题分析)
写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...
- Java - ArrayList源码分析
java提高篇(二一)-----ArrayList 一.ArrayList概述 ArrayList是实现List接口的动态数组,所谓动态就是它的大小是可变的.实现了所有可选列表操作,并允许包括 nul ...
- java ArrayList源码分析(转载)
1.ArrayList是一个相对来说比较简单的数据结构,最重要的一点就是它的自动扩容,可以认为就是我们常说的“动态数组”. 来看一段简单的代码: 12345 ArrayList<String&g ...
- java集合系列之ArrayList源码分析
java集合系列之ArrayList源码分析(基于jdk1.8) ArrayList简介 ArrayList时List接口的一个非常重要的实现子类,它的底层是通过动态数组实现的,因此它具备查询速度快, ...
- Java集合源码分析(二)ArrayList
ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线 ...
- Java集合源码分析(一)ArrayList
前言 在前面的学习集合中只是介绍了集合的相关用法,我们想要更深入的去了解集合那就要通过我们去分析它的源码来了解它.希望对集合有一个更进一步的理解! 既然是看源码那我们要怎么看一个类的源码呢?这里我推荐 ...
- Java集合干货——ArrayList源码分析
ArrayList源码分析 前言 在之前的文章中我们提到过ArrayList,ArrayList可以说是每一个学java的人使用最多最熟练的集合了,但是知其然不知其所以然.关于ArrayList的具体 ...
- Java入门系列之集合ArrayList源码分析(七)
前言 上一节我们通过排队类实现了类似ArrayList基本功能,当然还有很多欠缺考虑,只是为了我们学习集合而准备来着,本节我们来看看ArrayList源码中对于常用操作方法是如何进行的,请往下看. A ...
随机推荐
- java中byte,byte[]和int之间的转换
1>byte类型转换为,直接隐式转换,适用于要求保持数值不变,例如要求进行数值计算 如 byte b=0x01; int i=b; 2>另一种是要求保持最低字节中各个位不变,3个高字节全部 ...
- C++ 入门篇
C++基础入门 1 C++初识 1.1 第一个C++程序 编写一个C++程序总共分为4个步骤 创建项目 创建文件 编写代码 运行程序 1.1.1 创建项目 Visual Studio是我们用来编写 ...
- Linux下的strip命令学习
strip strip是Linux下的一个命令.可以用于给应用脱衣服,帮助我们抹除一些调试信息.(虽然不知道具体是什么,但是会用就好了) 在嵌入式开发领域用到的应该比较多 首先,先写一个示例看看 // ...
- SonarQube学习(五)- SonarQube之自定义规则使用
一.前言 古人云:"欲速则不达",最近真的是深有体会.学习也是如此,不是一件着急的事,越是着急越不会. 就拿SonarQube来说吧,去年年末就想学来着,但是想着想着就搁置了,有时 ...
- 借助window.performance实现基本的前端基础性能监控日志
借助window.performance实现基本的前端基础性能监控日志并二次重写console方法方便日常前端console日志的调试 npm install sn-console
- LeetCode841 钥匙和房间
有 N 个房间,开始时你位于 0 号房间.每个房间有不同的号码:0,1,2,...,N-1,并且房间里可能有一些钥匙能使你进入下一个房间. 在形式上,对于每个房间 i 都有一个钥匙列表 rooms[i ...
- 串的模式匹配算法1 BF算法
BF算法 字符串的模式匹配不一定要从主串的第一个位置开始,可以指定主串中查找的起始位置 pos. 2. 算法步骤: 1)分别利用计数器指针 i 和 j 指定主串和模式串即小字符串待比较的位置,初始化为 ...
- maven依赖与传递性依赖
目录 依赖范围 传递性依赖 依赖调节 可选依赖 本文主要是针对<maven实战>书中关键知识点的学习记录,未免有纰漏或描述不到之处,建议购买阅读原书 首先贴出一个pom常见的一些元素释义 ...
- 【Software Test】Basic Of ST
文章目录 Learning Objective Introduction Software Applications Before Software Testing What is testing? ...
- C语言目的概念(C语言学习笔记)
什么是目 目是针对操作符来说的,一个操作符影响两个操作数就表示该操作符为双目运算符 举个例子: 1+2 这里的加号影响了1和2两个操作数,所以"+"就是双目运算符 +1,-1 这里 ...