一段java代码

 String e = "q3234v";
List<String> list = new ArrayList<String>();
for (int i = 0; i < 25; i++) {
list.add(e);
}

执行这段代码,list会扩容几次

查看ArrayList的add方法,在添加元素之前会执行ensureCapacityInternal方法

这个时候size为0

   public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}

继续看ensureCapacityInternal方法,DEFAULT_CAPACITY的值为10,此时minCapacity为1

private static final int DEFAULT_CAPACITY = 10;
 private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}

这时候执行:ensureExplicitCapacity

此时minCapacity的值为10,接下来执行扩容方法

 private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
  private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
System.out.println(minCapacity+"------"+newCapacity); elementData = Arrays.copyOf(elementData, newCapacity);
}

minCapacity的值为10

新空间大小的值为 0+0>>1 = 0

所以第一次扩容完 后新空间大小为10

接下当list.add()执行到第11次的时候

minCapacity=11

newCapacity = 10+10>>1 = 15(1010>>1 = 101= 5)

i执行到16的时候,此时又发现空间不够了

minCapacity=16

newCapacity = 15+15>>1 = 22(1111>>1 = 7)

所以容量到25还需要再执行一次扩容

一共会执行4次扩容

这时候可能会发现在扩容的时候会执行 elementData = Arrays.copyOf(elementData, newCapacity)方法

所以为了减少copyOf的操作

在大概知道List的长度的情况下,在创建的时候应该给一个容量,在容量不够的情况下才会执行扩容操作

 public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}

ArrayList扩容分析的更多相关文章

  1. ArrayList的分析(转)

    一. ArrayList概述: ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境 ...

  2. ArrayList 扩容原理

    面试中经常问到的问题之一就是List的扩容机制了,他是怎么做到扩容的,大家都能答出来底层是数组,复制一个数组来扩容,但是再具体一点来说,大家就不知道该怎么说了,如果不看源码说这么多确实就差不多了,但是 ...

  3. ArrayList扩容机制

    一.先从 ArrayList 的构造函数说起 ArrayList有三种方式来初始化,构造方法源码如下: 1 /** 2 * 默认初始容量大小 3 */ 4 private static final i ...

  4. 都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事

    都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事 就用下面这段代码在jdk的三个版本运行看了下效果 import java.lang.reflect.Field; ...

  5. 分享知识-快乐自己:都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事

    都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事 就用下面这段代码在jdk的三个版本运行看了下效果: import java.lang.reflect.Field ...

  6. coding++:都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事

     都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事 就用下面这段代码在jdk的三个版本运行看了下效果: import java.lang.reflect.Fiel ...

  7. ArrayList扩容机制实探

    ArrayList初始化 问题:执行以下代码后,这个list的列表大小(size)和容量(capacity)分别是多大? List<String> list = new ArrayList ...

  8. external-resizer 源码分析/pvc 扩容分析

    kubernetes ceph-csi分析目录导航 基于tag v0.5.0 https://github.com/kubernetes-csi/external-resizer/releases/t ...

  9. ArrayList原理分析(重点在于扩容)

    首先,ArrayList定义只定义类两个私有属性: /** * The array buffer into which the elements of the ArrayList are stored ...

随机推荐

  1. Linux 特殊权限

    Linux 有三个高级权限suid,sgid,sticky. 1.suid suid 属性只能运用在可执行文件上,含义是开放文件所有者的权限给其他用户,即当用户执行该执行文件时,会拥有该执行文件所有者 ...

  2. SRS之HLS部署实例源码分析

    1. 综述 SRS 关于 HLS 的具体配置可见: HLS部署实例 SRS 关于 hls 的配置文件内容如下: listen 1935; max_connections 1000; daemon of ...

  3. Django入门------常见问题

    项目启动后仅本机可访问 1.修改 Django项目中的settings.py中的 ALLOWED_HOSTS 的值为 ['*']# 准许那些地址访问,* 表示任意地址ALLOWED_HOSTS = [ ...

  4. Nginx优化防爬虫 限制http请求方法 CDN网页加速 架构优化 监牢模式 控制并发量以及客户端请求速率

    Nginx防爬虫优化 Robots协议(也称为爬虫协议,机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可 ...

  5. javascript之Location对象

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. How to run a VBA macro when new mail is received in Outlook

    It can be very useful to run a VBA macro when new mail is received in Outlook. A customer asked me t ...

  7. Appium移动自动化测试(二)之appuim + 夜神模拟器

    环境搭建起来之后, 就可以开始移动自动化了. 但是使用自带的AVD开启模拟器, 速度实在太慢. 于是用夜神来做替代, 稍微能够有一些提速. 启动appuim 打开Appium,点击右上角Start按钮 ...

  8. SQL学习(八)日期处理

    不同数据库中,针对日期处理的函数不同 Oracle中常用日期函数 (1.sysdate: 获取当前系统时间 如: select sysdate() ----返回当前时间,包括年月日 时分秒 (2.to ...

  9. IDEA Cannot access alimaven (http://maven.aliyun.com/nexus/content/groups/public/)

    [ERROR] Plugin org.apache.maven.plugins:maven-compiler-plugin:3.1 or one of its dependencies could n ...

  10. docker commit命令

    docker commit命令用于基于一个容器来创建一个新的docker镜像. docker commit制作的镜像,除了制定镜像的人知道执行过什么命令,怎么生成的镜像,别人根本无从得知.建议使用的是 ...