数组(定长,有序的,随机访问)。ArrayList是Java在数组的基础上进行衍生出来的Java里的一种数据结构,它在拥有数据的特性之外,增加了可变性 (动态数组)。

属性

属性 备注
DEFAULT_CAPACITY 默认初始大小
EMPTY_ELEMENTDATA 空数组,申明了长度可能为0
DEFAULTCAPACITY_EMPTY_ELEMENTDATA 空数组 (无参构造时候的默认值)
elementData 承认数组元素
size 数组元素数量,注意和Lenth的

三种构造初始化

/**

带有参数的构造方法,

如果长度为0 则给一个默认的常量。

*/
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);
}
}
/**
直接给一个默认的空数组
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
   public ArrayList(Collection<? extends E> c) {
Object[] a = c.toArray();
if ((size = a.length) != 0) {
if (c.getClass() == ArrayList.class) {
elementData = a;
} else {
elementData = Arrays.copyOf(a, size, Object[].class);
}
} else {
// replace with empty array.
elementData = EMPTY_ELEMENTDATA;
}
}

分析

以上三种构建,两种有参,一种无参。主要区别就是 DEFAULTCAPACITY_EMPTY_ELEMENTDATAEMPTY_ELEMENTDATA在不同场景分别给值。

EMPTY_ELEMENTDATA是带参数的构建函数里长度为0的默认共享数组

DEFAULTCAPACITY_EMPTY_ELEMENTDATA是不带参数构造函数里长度为0的共享数组

对比老版本的JDK来看,会对初始化数组的时候解决是数度长度为空的情况下会 new Object[initialCapatity]的情况,减少不必要的内存开支。

在扩容机制也会针对不同的构造出的数组进行不同的扩容机制。

Add方法

    public boolean add(E e) {
//确保容量够不够,扩容机制
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
} // step 1
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
} // step 2. 计算容量
private static int calculateCapacity(Object[] elementData, int minCapacity) {
//判断是否是无参构造来的,为10个容量大小
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
//否则就给即将增长的长度
return minCapacity;
} // step 3
private void ensureExplicitCapacity(int minCapacity) {
//修改次数
modCount++; // 即将增长的长度比现的数组长度大就扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
} // step 4
private void grow(int minCapacity) {
//原始长度
int oldCapacity = elementData.length;
//新长度 = 原始长度 + (原始长度/2)
int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//尽量不扩容到 Intege 的最大值, 因为有些Vm的设计超过 MAX_ARRAY_SIZE 可能会 OOM错误 (OutOfMemoryError: Requested array size exceeds VM limit)
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}

分析

  1. add函数,可以看出来,每次扩容都是本身的 0.5
  2. 最大可以扩容到 Intege最大值,但也是在实际元素数量真的超过 MAX_ARRAY_SIZE的情况下。
  3. 建立不超过MAX_ARRAY_SIZE的原因是 OutOfMemoryError: Requested array size exceeds VM limit
  4. 为了避免开辟过多的数组空间,建立选择带参数的构造函数,以量申请。

Remove方法

借助了系统函数

/**
* 第一个参数是要被复制的数组
*
*   第二个参数是被复制的数字开始复制的下标
*
*   第三个参数是目标数组,也就是要把数据放进来的数组
*
*   第四个参数是从目标数组第几个下标开始放入数据
*
*   第五个参数表示从被复制的数组中拿几个数值放到目标数组中
*/ public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);

把最后一个元素置为null, size = size -1

elementData[--size] = null; // clear to let GC do its work

注意事项

  1. 禁止在 for``foreach里删除元素。
  2. ArrayList在多线程环境中是不安全的

最新文章

  1. 代码的坏味道(20)——过度耦合的消息链(Message Chains)
  2. Redis数据结构详解(一)
  3. 简化 Web 应用程序与 Windows Azure Active Directory、ASP.NET 和 Visual Studio 的集成
  4. Linux基础: 挂载镜像文件(Mount &amp; ISO)
  5. 函数buf_read_page
  6. win8.1恢复win7 CTRL+Space切换输入法
  7. Java: 实现顺序表和单链表的快速排序
  8. Java 多并发之原子访问(Atomic Access)
  9. python 学习 [day7]面向对象
  10. python怎么导入自定义函数
  11. oracle创建表空间、创建用户并赋予权限
  12. 调参必备---GridSearch网格搜索
  13. python之str字符串
  14. 如何使用openscad绘制一个简单的键帽.
  15. 前端框架之Vue.js
  16. android 框架层 常用类介绍
  17. H.264 RTP PAYLOAD 格式
  18. python获取aliyun ECS实例
  19. 简单读取 properties文件
  20. SharePoint 2016 Document Center Send To Connection

热门文章

  1. Asp.Net Core之Identity应用(上篇)
  2. SQL Server中如何让SQL语句对字符串大小写敏感
  3. 基于 WPF和ASP.NET Core 在线音视频聊天项目
  4. CSS样式写在JSP代码中的几种方法
  5. An=n的前n项和的前n项和
  6. Postman中文版客户端
  7. JavaScript学习总结6-apply
  8. 面试官:为什么Vue中的v-if和v-for不建议一起用?
  9. canvasToTempFilePath: fail SecurityError: The operations is insecure
  10. go语言编译过程概述