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 ... 
随机推荐
- 第二章  信号量及条件变量(三)——> 重点
			2.4.4 信号量的应用 1. 利用信号量实现进程互斥 为使多个进程能互斥的访问某临界资源,只需为该资源设置一个互斥信号量mutex,并设置其初值为 1 ,然后讲个进程访问该资源的临界区CS置于w ... 
- 基于jupyter lab搭建网页编程环境并添加自定义python kernel和matlab kernel以及plotly的使用
			内容转载自我的博客 目录 说明 1. 创建虚拟环境jupyter 2. 安装nodejs(用于jupyterlab安装扩展) 3. 安装pip包 4. 使用jupyterlab 5. 配置jupyte ... 
- 关于Webservice接口对接相关总结
			Webservice接口对接 因为近期处理了很多关于Webservice的接口对接,所以这篇文章是对近期自己的学习做一个简单的总结. 一: 对于接口对接,建议首先需要了解一下WSDL文件,以及入参的S ... 
- CSS卡片旋转
			html{ perspective: 800px; } body{ display:flex; flex-wrap: wrap; } .card{ transform-style: preserve- ... 
- Debian安装HomeBrew
			前言 HomeBrew 的用处我想使用 Mac 的开发人员都知道, 本篇讲解如何在 Debian 上安装 BrewLinux 更新: 后来发现并不是很好用, 不建议使用 官方推荐的脚本安装 注意这里只 ... 
- 安装weblogic 11g
			参考 https://blog.csdn.net/z69183787/article/details/38401013 https://blog.csdn.net/wjf8882300/article ... 
- ps -eo 用户自定义格式显示
			[root@ma ~]# ps -eo pid,ucomm|head -3 PID COMMAND 1 init 2 kthreadd[root@ma ~]# ps axu|head -3USER P ... 
- 鸿蒙的远程交互组件应用及微信小程序的远程交互组件应用
			注:鸿蒙的远程交互组件应用相对复杂 ,访问网络时,首先要配置网络权限,华为官方文档有问题,在此引用我老师配置的模板,见附件 过程:1.导入鸿蒙的网络请求模块fetch 2.发起对服务器的请求(在这过程 ... 
- Jquery实现对Array数组实现类似Linq的Lambda表达式的Where方法筛选
			平时使用Linq,习惯了Lambda表达式,用着非常顺手,奈何在Jquery里面不能这样用,只能循环一个个判断.趁空闲时间找了找,自己写了这样的扩展方法.目前写出了三种方案,没有比较性能,觉得都可以用 ... 
- Redis持久化之RDB和AOF
			Redis是一个键值对数据库服务器,由于Redis是内存数据库,那么有很多内存的特点,例如掉电易失,或者进程退出,服务器中的数据也将消失不见,所以需要一种方法将数据从内存中写到磁盘,这一过程称之为数据 ... 
