minCapacity - elementData.length > 0
成立,所以会进入 grow(minCapacity)
方法 。
minCapacity - elementData.length > 0
不成立 , 所以不会进入 (执行)grow(minCapacity)
方法 。grow()
/*** 要分配的最大数组大小*/private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;/*** ArrayList扩容的核心方法 。*/private void grow(int minCapacity) {// oldCapacity为旧容量,newCapacity为新容量int oldCapacity = elementData.length;//将oldCapacity 右移一位,其效果相当于oldCapacity /2,//我们知道位运算的速度远远快于整除运算 , 整句运算式的结果就是将新容量更新为旧容量的1.5倍,int newCapacity = oldCapacity + (oldCapacity >> 1);//然后检查新容量是否大于最小需要容量,若还是小于最小需要容量,那么就把最小需要容量当作数组的新容量,if (newCapacity - minCapacity < 0)newCapacity = minCapacity;// 如果新容量大于 MAX_ARRAY_SIZE,进入(执行) `hugeCapacity()` 方法来比较 minCapacity 和 MAX_ARRAY_SIZE,//如果minCapacity大于最大容量 , 则新容量则为`Integer.MAX_VALUE`,否则 , 新容量大小则为 MAX_ARRAY_SIZE 即为 `Integer.MAX_VALUE - 8` 。if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = https://www.huyubaike.com/biancheng/Arrays.copyOf(elementData,newCapacity);}
int newCapacity = oldCapacity + (oldCapacity >> 1),所以 ArrayList 每次扩容之后容量都会变为原来的 1.5 倍左右(oldCapacity 为偶数就是 1.5 倍 , 否则是 1.5 倍左右)! 奇偶不同,比如 :10+10/2 = 15,33+33/2=49 。如果是奇数的话会丢掉小数.我们再来通过例子探究一下>
(移位运算符):>>1 右移一位相当于除 2,右移 n 位相当于除以 2 的 n 次方 。这里 oldCapacity 明显右移了 1 位所以相当于 oldCapacity /2 。对于大数据的 2 进制运算 , 位移运算符比那些普通运算符的运算要快很多,因为程序仅仅移动一下而已,不去计算,这样提高了效率,节省了资源
grow()
方法 :- 当 add 第 1 个元素时,oldCapacity 为 0 , 经比较后第一个 if 判断成立,newCapacity = minCapacity(为 10) 。但是第二个 if 判断不会成立,即 newCapacity 不比 MAX_ARRAY_SIZE 大,则不会进入
hugeCapacity
方法 。数组容量为 10,add 方法中 return true,size 增为 1 。 - 当 add 第 11 个元素进入 grow 方法时,newCapacity 为 15,比 minCapacity(为 11)大,第一个 if 判断不成立 。新容量没有大于数组最大 size , 不会进入 hugeCapacity 方法 。数组容量扩为 15,add 方法中 return true,size 增为 11 。
- 当第16个元素进入容器时再次扩容
- java 中的
length
属性是针对数组说的,比如说你声明了一个数组,想知道这个数组的长度则用到了 length 这个属性. - java 中的
length()
方法是针对字符串说,如果想看这个字符串的长度则用到length()
这个方法. - java 中的
size()
方法是针对泛型集合说的,如果想看这个泛型有多少个元素,就调用此方法来查看!
hugeCapacity()
从上面
grow()
方法源码我们知道: 如果新容量大于 MAX_ARRAY_SIZE,进入(执行) hugeCapacity()
方法来比较 minCapacity 和 MAX_ARRAY_SIZE , 如果 minCapacity 大于最大容量,则新容量则为Integer.MAX_VALUE
,否则,新容量大小则为 MAX_ARRAY_SIZE 即为 Integer.MAX_VALUE - 8
。private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();//对minCapacity和MAX_ARRAY_SIZE进行比较//若minCapacity大,将Integer.MAX_VALUE作为新数组的大小//若MAX_ARRAY_SIZE大 , 将MAX_ARRAY_SIZE作为新数组的大小//MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}
System.arraycopy()
和 Arrays.copyOf()
阅读源码的话,我们就会发现 ArrayList 中大量调用了这两个方法 。比如:我们上面讲的扩容操作以及
推荐阅读
- Java单例模式,看这一篇就够了
- 微信支付v3接口的 官方 Java SDK
- Java函数式编程:二、高阶函数,闭包,函数组合以及柯里化
- 夯实Java基础,一篇文章全解析线程问题
- 四 Java多线程-ThreadPool线程池-2
- 生成器函数 javascript异步编程之generator与asnyc/await语法糖
- Java Timer使用介绍
- 三 Java多线程-ThreadPool线程池
- 二 Java多线程-线程关键字
- 二 Java 编码那些事