ArrayList 扩容机制:
ArrayList 的底层是一个Object[]数组。扩容的本质就是创建一个新的、容量更大的数组然后将原数组中的元素复制到新数组中最后让 ArrayList 内部的数组引用指向这个新数组。具体来说初始化如果使用无参构造器new ArrayList()在JDK 1.8及以后初始容量是0而不是10JDK 1.7。只有在第一次调用add()方法时会通过grow()方法将容量懒加载为默认的10。当然也可以使用带初始容量的构造器new ArrayList(int initialCapacity)来指定初始大小。扩容时机当调用add()方法添加元素且当前元素个数size 1 当前内部数组的长度时就会触发扩容。扩容计算ArrayList扩容的计算是在一个grow()方法里面grow方法先尝试将数组扩大为原数组的1.5倍。边界处理如果 1.5 倍后的容量仍然小于所需的最小容量例如addAll一次性加入大量元素那么新容量直接取所需的最小容量。如果新容量超过了定义的最大数组长度MAX_ARRAY_SIZE则会进行hugeCapacity()处理最终可能将容量设为Integer.MAX_VALUE或者 抛出OOM。复制若新的容量满足需求会调用一个Arrays.copyof方法, 将所有的元素从旧数组复制到新数组中总结由于扩容涉及数组复制时间复杂度O(n)频繁扩容会影响性能。所说义建议使用ArrayList(int initialCapacity)构造器来指定初始容量避免多次扩容。为什么是1.5倍选择1.5 倍即右移一位oldCapacity 1是为了在时间与空间之间做平衡。如果增长倍数太小如 1.1 倍扩容次数频繁复制成本高。如果增长倍数太大如 2 倍可能会浪费较多内存空间。1.5 倍既能保证均摊下来add操作的时间复杂度依然是O(1)又能避免过度的内存浪费。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2445824.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!