ArrayList-添加,删除原理-源码扩容grow(int minCapacity)

31 篇文章 0 订阅
订阅专栏


赠人玫瑰,手有余香,你的点赞,我的动力
更多分享可见:
在这里插入图片描述

总结

所谓动态数组的扩容,就是包装下面这个api 。
Arrays.copyOf(elementData, newCapacity);
没有耐心的小伙伴直接跳转到 grow(minCapacity) 目录处

1预备知识

运用:
1 Arrays.copyOf(elementData, newCapacity); //扩容数组的api
2 System.arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length); //复制数组的api

  • 1
import java.util.Arrays;

public class ArrayDemo {
	public static void main(String[] args) {
    	int[] arr1 = {1, 2, 3, 4, 5}; 
    	int[] arr2 = Arrays.copyOf(arr1, 5);
    	int[] arr3 = Arrays.copyOf(arr1, 10);
    	for(int i = 0; i < arr2.length; i++) 
        	System.out.print("arr2:"+arr2[i] + " "); 
    		System.out.println();
    	for(int i = 0; i < arr3.length; i++) 
        	System.out.print("arr3:"+arr3[i] + " ");
	}
} 

运行结果:
arr2:1 2 3 4 5
arr3:1 2 3 4 5 0 0 0 0 0

可见扩容后的数组 补充了几个零,如果数组是对象,应该是补充几个null

  • 2
    System.arraycopy(Object src, int srcPos,
    Object dest, int destPos,
    int length);

参数说明:
src:源对象
srcPos:源数组中的起始位置
dest:目标数组对象
destPos:目标数据中的起始位置
length:要拷贝的数组元素的数量

简单说:
我要复制一个名字为src 的数组,
从src 数组下标为srcPos 的位置开始复制,
复制的个数是 length ,
复制的内容写到哪里 dest 数组中!
从dest 数组的的destPos 下标位置开始复制!

2源码分析

源码:add(E e) 原理实现

add(E e):添加一个元素到列表的末尾。

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 确保数组大小够不是否,需要扩容不。
        /*1 elementData 是Arraylist中存放元素的真正数组,size是当前数组中存了几个元素,而不是数组的长度!!!
        *2 把添加的元素放入数组中已存入元素个数的+1位置!
        */
         elementData[size++] = e;
        return true;
    }

记住size+1 代表加入一个元素后当前总元素的数量 很重要!!!!

  • 下一步
    ensureCapacityInternal(size + 1); 如何扩容
    private void ensureCapacityInternal(int minCapacity) {
    //如果new ArrayList() 这样的实例对象,则ArrayList大小就是DEFAULT_CAPACITY--> 10大小
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
	//确定是否需要扩容,下一步进入
        ensureExplicitCapacity(minCapacity);
    }
  • 下一步
    要注意:当前的minCapacity 除了无惨构造实例化设置10 ,其他情况就是等于 size+1 ,代表当前list列表中的需要存储的总元素个数
    ensureExplicitCapacity(minCapacity);
   private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // 如果小存储的的总元素个数大于当前数组的长度,则扩容执行grow(minCapacity)
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

源码:grow(minCapacity) ArrayList核心

  • 下一步 grow
    grow(minCapacity)
 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
             //表示扩容一半,>>1 代表右移一位,在数学上就等同于除2,所以本身长度 oldCapactiy+自身一半,  这是扩容后的长度。
        int newCapacity = oldCapacity + (oldCapacity >> 1); 
        //扩容前有两个情况需要注意下:
       //情况1 如果扩容后的长度还是小于当前需要存入的个数minCapacity ,为扩容的大小
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
       //情况2 如果扩容后的长度,大于ArrayList 类中规定的最大长度,处理情况,暂时不看
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //程序走到这里就代表老老实实的扩容了,怎么样看到Arrays.copyOf()  很熟悉了吧
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

  • 下一步
    我们在继续分析Arrays.copyOf(elementData, newCapacity);
    public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());//点击下一步
    }

  • 下一步
   public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
   		/*下边三元表达式,代码看起来很恶心,表达的意思是:要被复制的目标是不是Object[]  类型的
   		*如果是重新建一个Object[newLength]  数组,记着newLength 传递的是我们需要扩容数组的大小!!
   		*如果不是则把目标包装成一个数组,大小也是newLength
   		*最终目的就是保证传入给System.arraycopy() 方法中参数"copy" 的值是一个我们扩容后的新数组
   		*/
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
       //眼熟吧!!!上面例子中有解释     
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

源码:remove(int index)删除实现

如果删除23 这个数字,要把位置在7,8,9上的元素移动到6,7,8的位置上!
在这里插入图片描述

所以源码分析

    public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);
		//复制的个数
        int numMoved = size - index - 1;//删除23,则后面的元素的位置index 7 8 9,所以需要3个
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);//numMoved代表需要复制几个!
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

更多记录请看:
在这里插入图片描述

ArrayList 原理剖析
m0_62098995的博客
03-28 791
在了解这个类之前,需要先知道为什么会有这个类,它解决了什么问题。ArrayList 的出现是为了解决数组的缺陷,使用 java 的数组需要在创建数组时便确定数组的容量,因为数组本身不会自动扩容。所以对于数组内元素数量不确定的场景,都可以用 ArrayList 来简化代码。 既然 ArrayList 解决了数组扩缩容问题,那么其就相当于是一种创新型的数据结构,对应的它也需要解决好增删查改的问题,后面我们就从增删查改四个维度看一下它的实现方案。 对 ArrayList 的基础操作 增 Add 数据的第一步是创建
Java集合-从源码分析ArrayList扩容机制
jinyangjie的博客
01-29 1112
  我们知道,Java中标准数组是定长的,在数组被创建之后,它们不能被加上或缩短。ArrayList是List接口的实现类,支持动态增长的数组。下面从源码了解ArrayList扩容机制。 一、ArrayList的构造函数   ArrayList有三种方式初始化,源码如下。 1.1 无参构造函数   构造一个空列表,长度为0 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; public ArrayL
Java集合---ArrayList的实现原理
weixin_34198762的博客
09-01 646
目录:       一、 ArrayList概述       二、 ArrayList的实现                   1) 私有属性                  2) 构造方法                  3) 元素存储                  4) 元素读取                  5) 元素删除                 6) 调...
ArrayList增删方法原理
weixin_42490383的博客
06-26 475
ArrayList grow(int minCapacity)
weixin_30340745的博客
12-24 189
ArrayList grow(int minCapacity) 转载于:https://www.cnblogs.com/yangzihong/p/10170359.html
ArrayList的基本工作原理详解add
811
05-16 4488
ArrayList其实就是一个长度可变的数组,看源码就是知道,就是是一个Object[]。 ArrayList是unsynchronized。 因为底层由数组承载,那么需要连续的内存空间,所以空间复杂度是O(n)。 如果按下标直接去get(index)或者直接add(e)到数组的尾部,那么时间复杂度是O(1)。 如果要remove(index),或者add(index,e)那么时间复杂度为O
ArrayList -- 使用ensureCapacity()在不知道数据多少的情况 提高扩容效率
落云阁
05-31 497
ensureCapacity()方法是什么? ensureCapacity()是 ArrayList 源码中的方法,是提供给用户调用的 ensureCapacity()方法能做什么? 在 ArrayList.add操作 大量元素之前用 ensureCapacity 方法,以减少 增量重新分配1的次数。 自定义扩容倍数(默认是1.5倍),这是我推理出的作用(仅供讨论) 分析推理过程 首先减少增量重新分配的方法我所知的有两种: new ArrayList(初始化容量)初始化容量 ensureCapacit
ArrayListCopyOnWriteArrayList详解和源码剖析【扩容机制】
Charte的博客
03-15 1537
在此列表中的指定位置插入指定的元素。 先调用 rangeCheckForAdd 对index进行界限检查;然后调用 ensureCapacityInternal 再将从index开始之后的所有成员后移一个位置;将element插入index位置;最后size加1。
ArrayList扩容原理源码讲解
03-30
ArrayList扩容原理源码如下: ```java private void grow(int minCapacity) { // 获取当前ArrayList容量 int oldCapacity = elementData.length; // 容量增加1.5倍,右移1位相当于除以2 int newCapacity = ...
ArrayList动态扩容原理(部分源码展示)
weixin_42765792的博客
05-12 230
ArrayList动态扩容原理(部分源码展示) ArryList的动态扩容:每当执行添加元素的方法,ArrayList会检查内部数组的容量是否足够,如果不够,它就会以当前容量的1.5倍来重新构建一个数组,将旧元素Copy到新数组中,然后丢弃旧数组。 核心方法: ArrayList的grow方法会判断当前数组容量是否足够,不够就通过copyOf()方法创建一下新的数组并把旧数组的内容copy过去 private void grow(int minCapacity) { // overflow-
深入Java集合学习系列:ArrayList的实现原理
03-18
NULL 博文链接:https://zhangshixi.iteye.com/blog/674856
ArrayList实现原理
weixin_34049948的博客
01-30 154
概述 ArrayList可以简单的看作是动态数组,相对于普通的数组它可以动态的增加容量或者减少容量。要注意的是ArrayList并不是线程安全的,因此一般建议在单线程中使用ArrayList。 实现原理 继承关系 public class ArrayList<E> extends AbstractList<E> i...
ArrayList如何实现增删元素及其缺陷
loading_123的博客
06-27 285
ArrayList提供如下构造方法: public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA;
手动实现ArrayList底层增删查原理
最新发布
Pi_Zi_Hai_Ou的博客
07-13 130
手动一个ArrayList底层的增删查过程如下:新建一个包其中一个底层类一个测试类首先实现向ArrayList添加:在实现添加之前需要声明一个私有集合所有用户向ArrayList中存入的数据都会到这个集合中:在MyArrayList这个类创建一个add方法,obj是用户使用add方法时带入的数据:首先用户第一次使用时这个ArrayList时,他底层的arr集合肯定是个空的,所以需要先做一个判断。
解读ArrayList中的grow(int minCapacity)方法
Anakki的博客
01-10 6318
查看源码: /** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * * @param minCapacity the desired...
剖析ArrayList底层和添加元素的原理
xiezhi_1130的博客
12-19 1687
我们在实际工作中使用List情况非常多。 那么我们来看下ArrayList的 底层是如何实现的 其实ArrayList底层是一个Object 的 数组 我们来看下jdk中的源代码 如下 public class ArrayList&lt;E&gt; extends AbstractList&lt;E&gt; implements List&lt;E&gt;, Random...
ArrayList动态添加基本原理
osillto的博客
06-01 275
1.一开始如果是空的构造函数时,会创造一个空的object数组,如果给定了数组的长度则创建给定长度的数组 2.在调用第一次Add方式的时候,创建了一个10个长度的Object数组 3.在不断的调动add方法会触发grow()方法 奔着n+(n>>1)(向右移动一位,基本上就是每次乘以1.5(1.5是综合测试所得,基本上这样的效率比较高)) 动态添加具体的实现代码: private void grow(int minCapacity) {//传入原数组长度加一 int oldCapac
数据结构复习之ArrayList添加元素源码分析
千里之行,始于足下
04-18 178
ArrayList添加元素源码分析 分析元素放入及扩容机制 package SourceTest; import java.util.ArrayList; import java.util.List; //测试程序 public class ArrayListTest { public static void main(String[] args) { List list...
ArrayList 增删改查等操作的源码分析
@另维
08-01 1040
ArrayList 的数据结构 ArrayList 底层的数据结构就是数组,数组元素类型为 Object 类型,即可以存放所有类型数据。对该类的实例的所有操作底层都是基于数组的。 实际大小:size 容量:CAPACITY 继承结构 ArrayList 是直接继承自 AbstractList,为什么不是 List? 这里的设计思想:我们知道接口中的方法都是抽象的,而抽象类中可以有抽象方法,还可以有具体的方法。这里是让 AbstractList 实现接口中通用方法,而它具体的子类 ArrayList
写文章

分类专栏

  • demo 1篇
  • 随笔 14篇
  • 算法 12篇
  • 操作系统 1篇
  • 问题记录 4篇
  • 技巧 1篇
  • 笔记 2篇
  • 生活法律常识 1篇
  • 日志 2篇
  • http 1篇
  • li
  • ELK 1篇
  • kafka 1篇
  • 设计模式 1篇
  • spring 2篇
  • 保险
  • zookeeper 1篇
  • excel 1篇
  • 安装
  • 网络 12篇
  • java前后台交互 1篇
  • java框架 3篇
  • springBoot 2篇
  • 数据库 1篇
  • java 31篇
  • JVM 1篇
  • linux 5篇
  • springMVC 1篇

最新评论

  • 并发编程 之volatile 关键字 和 单例模式的双重检查

    CSDN-Ada助手: 哇, 你的文章质量真不错,值得学习!不过这么高质量的文章, 还值得进一步提升, 以下的改进点你可以参考下: (1)使用更多的站内链接;(2)提升标题与正文的相关性。

  • demo篇---同一个用户开启多个webSocket连接

    m0_59263191: 每个网页有独立的websocketsession要怎么实现

  • ip类型 ,子网掩码, 网关 ,主机位数,网络位数,子网数 ,这都什么鬼!终于明白了!

    il_ndsc: 最后一点有必要设置成一个25和一个26吗?都用25不就可以实现了?用26的意义是什么?剩出来留给其他子网使用吗?

  • 通俗易懂HashMap为何喜欢2的倍数扩容,(数组容量是2的次幂)

    zhuozuozhi: 没理解你的意思,好像跟我的回答没有关系

  • 通俗易懂HashMap为何喜欢2的倍数扩容,(数组容量是2的次幂)

    zhuozuozhi: 没有理解你的意思

最新文章

  • 随笔篇-操作系统的int80
  • dnsmasq搭建
  • 离线安装ntp
2022年1篇
2021年44篇
2020年22篇
2019年22篇
2018年21篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家甘南玻璃钢卡通雕塑江津玻璃钢景观雕塑江苏室内商场美陈供应商丽江玻璃钢雕塑直供安徽商场节庆美陈雕塑加工温州鼎湖玻璃钢人物雕塑玻璃钢泡沫雕塑造价玻璃钢花盆哪家服务好玉树玻璃钢雕塑工程玻璃钢仿真仙鹤雕塑曲阳玻璃钢彩绘雕塑威海市玻璃钢人物雕塑批发厂家恩平玻璃钢花盆花器海拉尔玻璃钢雕塑厂家衡水玻璃钢人物雕塑厂家文山玻璃钢雕塑批发春季商场美陈戴蝴蝶结抽象人物玻璃钢雕塑制作佛山玻璃钢雕塑电话多少宿州多彩玻璃钢雕塑价位山西仿古玻璃钢雕塑厂家天水仿真人物玻璃钢雕塑定做云浮玻璃钢造型雕塑女娲补天玻璃钢雕塑广东水果玻璃钢雕塑批发正方形玻璃钢花盆价格广东玻璃钢雕塑企业河北大型主题商场美陈销售深圳玻璃钢花盆厂青海玻璃钢雕塑圆雕香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化