重新理解基础数据结构(动态数组,链表)
1 最近在准备面试发现 ArrayList 扩容机制总是死记硬背过段时间就忘。索性花几小时彻底啃一遍源码争取一次拿下、终身不忘。2 ArrayList 底层是动态数组。Java 原生数组一旦定义长度就不可变使用场景受限。ArrayList 就是对数组的一层优化封装让我们可以动态增删元素提高开发效率。3 ArrayList底层(这里是JDK1.8)3.1 在创建数组时,底层会创建一个新的Object[]的空数组只有当你添加元素时即add()方法时,先判断是不是原来的空数组,是的话会和10取最大值也就是说只有第一次添加元素才能进入上面的判断,这样capacity就是10了3.2 当数组的元素个数超过和等于10,就会触发扩容grow()后续每次扩容是将int newCapacity oldCapacity (oldCapacity 1) newCapacity 10 101 等于15,扩容成原来的1.5倍 这也是为什么是1.5倍,为什么这么设计是为了空间和性能上的考虑,1 因为能最大化复用之前的内存碎片,举个列子2倍的 [空闲10],[空闲20],[空闲40],[空闲80] 16010204080,就是前面释放的内存随便不够扩容之后使用,1.5倍10 → 15 → 22 → 33,10 15 22 47 ≥ 33,可以够扩容后新数组使用,这就是最大化复用之前释放的内存碎片.2 平衡内存占用和扩容次数,3 1.5 倍可以利用二进制位移高效计算3.3 扩容的长度的临界值判断,新的数组长度newCapacity和MAX_ARRAY_SIZE比较,MAX_ARRAY_SIZE是Integer.MAX_VALUE-8,这8个字节是用存储数组这个对象头的信息,如果newCapacity是负数,直接OOM说明扩容是超出了Integer.MAX_VALUE了,如果比Integer.MAX_VALUE大就返回给你Integer.MAX_VALUE,否则就返回Integer.MAX_VALUE-83.4 最后将原数组拷贝到新数组中赋值给原数组
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2517847.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!