java怎么数组缩容,谈谈你所不知道的ArrayList缩容

前言

每当大家谈起ArrayList都只会关注它的自动扩容机制,但是大多数人却不会去关注ArrayList是否会自动缩容。下面会根据几个问题让大家了解一下ArrayList的缩容机制。

PS:缩容指的是ArrayList中的Object数组elementData的大小缩减

ArrayList是否会自动缩容?

既然ArrayList的自动扩容一般是发生在add()和addAll()方法中,那么当ArrayList调用remove()方法时是否会自动缩容呢?

ArrayList#remove()源码分析

remove()方法有两个

入参为数组下标返回被删除的元素

入参为数组元素返回数组下标

PS:本文研究的JDK源码为Oracle JDK 1.8

这里对第1个方法的源码进行分析

public E remove(int index) {

// 校验传入的下标是否大于或等于当前ArrayList的长度size

// 如果超过直接抛出IndexOutOfBoundsException

rangeCheck(index);

// 修改次数自增

// modCount是用于快速失败机制的,这里不展开

modCount++;

// 获取需要删除的元素的值

E oldValue = elementData(index);

// 计算数组从需要删除的元素后需要移动的元素个数

int numMoved = size - index - 1;

if (numMoved > 0)

// 使用System.arraycopy()来进行数组元素左移

System.arraycopy(elementData, index+1, elementData, index,

numMoved);

// 多余的元素标记为null便于gc回收,同时size自减

elementData[--size] = null;

// 返回被删除的元素值

return oldValue;

}

复制代码PS:System#arraycopy()并不会影响源数组和目标数组的长度。

ArrayList#remove()源码图解

如果觉得源码比较难懂,可以参考下面的ArrayList的remove()方法关键过程图解c9edc96880794a2720a111a9b4c5ca51.png

从上面可以看出ArrayList在执行remove()方法时,内置的Object数组实际上并没有减少长度,只是通过数组部分元素左移、最后一个元素置为null同时size自减来实现删除操作。而且入参为数组元素返回数组下标的remove()、removeAll()和removeRange()也是类似的做法。

ArrayList#clear()源码分析

除了remove()以外,ArrayList还有一个clear()方法用来对数组进行清空。那它又是怎么工作的呢?实际上简单到我不敢相信

public void clear() {

// 修改次数自增

modCount++;

// 遍历数组并置为null便于gc回收

for (int i = 0; i < size; i++)

elementData[i] = null;

// 直接给size赋值为0

size = 0;

}

复制代码

结论

从上面两节源码的分析可以得知,实际上ArrayList是不提供自动缩容机制的。其实这样设计也无可厚非,毕竟很多时候都无法判断是否需要进行缩容操作。既然没有自动缩容,那ArrayList可以进行缩容吗?

ArrayList可以进行缩容吗?

当然是有的,那就是trimToSize()方法。这个方法会将ArrayList内置的数组缩容到当前的size,源码也特别简单,就是给elementData一个对应size长度的数组。源码如下

public void trimToSize() {

// 修改次数自增

modCount++;

// 判断当前是否需要缩容

if (size < elementData.length) {

// 如果size为0,直接给elementData赋值内置的空数组

// 不为0则创建一个size长度的新数组

elementData = (size == 0)

? EMPTY_ELEMENTDATA

: Arrays.copyOf(elementData, size);

}

}

复制代码

总结

ArrayList的remove只是通过数组部分元素左移、最后一个元素置为null同时size自减来实现删除操作。实际上并未对elementData进行缩容。

可以使用trimToSize()方法对elementData进行缩容。

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[谈谈你所不知道的ArrayList缩容]http://www.zyiz.net/tech/detail-140458.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值