1. ArrayList 实现了RandomAccess接口, RandomAccess接口用于标记是否可以随机访问

2. 继承了AbstractList类, 因此获取了modcount , modcount用于实现快速失败机制, 如果list有修改, 那么modcount自增

3. ArrayList不支持并发, 是非线程安全的

4. 支持存放null元素

5. 扩容, 每次都是原来大小的1.5倍

public void ensureCapacity(int minCapacity) {
//如果elementData不等于EMPTY_ELEMENTDATA(因为初始化时有可能等于), 那么minExpand为0或者DEFAULT_CAPACITY
//如果elementData不为空minExpand为0, 可以用这个来处理minCapacity为负数的情况
//如果elementData为空, 那么就是默认容量
int minExpand = (elementData != EMPTY_ELEMENTDATA)
// any size if real element table
? 0
// larger than default for empty table. It's already supposed to be
// at default size.
: DEFAULT_CAPACITY; //如果最小容量大于minExpand, 那么进行明确扩容
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
} //已确定扩容minCapacity
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //修改次数加1 // overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
} private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//newCapacity为oldCapacity的1.5倍, 这里有可能会溢出为-1
int newCapacity = oldCapacity + (oldCapacity >> 1);
....
}

6. lastIndexOf, contains, indexOf方法用于查找, 时间复杂度均为O(N), 使用对象的equals方法进行比较
7. clone() 方法为深复制, 所谓深复制和浅复制的区别在于复制内部引用对象时的不同, 深复制会将原来的对象重新clone一份, 让复制对象的引用指向新对象, 而浅复制仅仅复制引用, 仍指向原来的对象. java Object中的clone方法为浅复制

8. set() 和 get() 为O(1)的时间复杂度

9. 调用ensureCapacityInternal(int) 会使modCount+1. ArrayList中的添加元素都会调用这个函数 ,例如add(object)和add(int,Object)

10. add(Object) 和add(int,Object)的时间复杂度为O(N), 因为底层数组的复制移动

11. remove(int)方法也会使modCount+1, 时间复杂度为O(N) , 同时内部使用elementData[--size] = null;用来防止内存泄漏, 以便gc释放内存

12. remove(Object) 使用了fastRemove非法, fastRemove如果未找到删除元素, 那么modCount是不会变的, 反之modCount+1 , 之所以fastRemove称之为fast是因为使用了System.arrayCopy进行元素移动, System.arrayCopy是一个native方法, 可以躲避java访问数组时的下标检查.

13. clear方法, modCount+1

14. addAll(...) 都会调用ensureCapacityInternal方法,  从而使modCount+1, O(N)的时间复杂度

15. removeAll(object)//补集和retainAll(object)//交集 都可以使用batchRemove方法, O(N^2)的时间复杂度, modCount+1.

16. 快速失败机制体现在容器的遍历中, Iterator会在对象初始化过程中保存当前容器的modCount, 并在每次遍历检查modCount, 如果两者不一致, 那么说明容器在遍历时被修改, 抛出ConcurrentModificationException.

   private class Itr implements Iterator<E> {

        int expectedModCount = modCount;

        public E next() {
checkForComodification();
int i = cursor;
...
} public void remove() {
...
checkForComodification(); ...
} final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}

java arraylist源码记录的更多相关文章

  1. Java ArrayList源码剖析

    转自: Java ArrayList源码剖析 总体介绍 ArrayList实现了List接口,是顺序容器,即元素存放的数据与放进去的顺序相同,允许放入null元素,底层通过数组实现.除该类未实现同步外 ...

  2. Java ArrayList源码分析(有助于理解数据结构)

    arraylist源码分析 1.数组介绍 数组是数据结构中很基本的结构,很多编程语言都内置数组,类似于数据结构中的线性表 在java中当创建数组时会在内存中划分出一块连续的内存,然后当有数据进入的时候 ...

  3. Java ArrayList源码分析(含扩容机制等重点问题分析)

    写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...

  4. Java - ArrayList源码分析

    java提高篇(二一)-----ArrayList 一.ArrayList概述 ArrayList是实现List接口的动态数组,所谓动态就是它的大小是可变的.实现了所有可选列表操作,并允许包括 nul ...

  5. Java——ArrayList源码解析

    以下针对JDK 1.8版本中的ArrayList进行分析. 概述     ArrayList基于List接口实现的大小可变的数组.其实现了所有可选的List操作,并且元素允许为任意类型,包括null元 ...

  6. Java|ArrayList源码分析|add()增加方法和grow()扩容方法

    本文结构: 1.介绍特点 2.基本方法 3.重点源码分析 1.介绍特点 ArrayList: 是List的一个具体实现子类,是List接口的一个数组实现 (里面必定维护了一个数组). 默认初始容量10 ...

  7. java ArrayList源码分析(转载)

    1.ArrayList是一个相对来说比较简单的数据结构,最重要的一点就是它的自动扩容,可以认为就是我们常说的“动态数组”. 来看一段简单的代码: 12345 ArrayList<String&g ...

  8. 【源码阅读】Java集合之一 - ArrayList源码深度解读

    Java 源码阅读的第一步是Collection框架源码,这也是面试基础中的基础: 针对Collection的源码阅读写一个系列的文章,从ArrayList开始第一篇. ---@pdai JDK版本 ...

  9. Java集合源码分析(一)ArrayList

    前言 在前面的学习集合中只是介绍了集合的相关用法,我们想要更深入的去了解集合那就要通过我们去分析它的源码来了解它.希望对集合有一个更进一步的理解! 既然是看源码那我们要怎么看一个类的源码呢?这里我推荐 ...

随机推荐

  1. pytorch下可采用visidom作为可视化工具

    2018/9/18更新  感觉tensorboardX插件更好用,已转用https://github.com/lanpa/tensorboardX 更新:新版visdom0.1.7安装方式为:cond ...

  2. C++ 错误解决 —— internal compiler error

    问题: g++ 编译时,报错: g++: internal compiler error: Killed (program cc1plus) 出错原因: 出错的原因是(虚拟机)运行内存不足,而大量te ...

  3. jquery 遍历find()与children()的区别

    find():返回被选元素的后代元素.后代是子.孙.曾孙,依此类推. http://blog.csdn.net/zm2714/article/details/8117978 http://www.jb ...

  4. linux监控平台搭建-磁盘

    linux监控平台搭建-磁盘 磁盘:随着大数据快速发展.人工智能.自动化.云平台.数据量指数的增长.磁盘的使用量也在增长.目前的机器基本上采用SSD或者SATA盘,一直有人比较那个好.会不会使用时间短 ...

  5. 手动创建DataTable并绑定gridview

    原文发布时间为:2008-08-04 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...

  6. 37深入理解C指针之---结构体与指针

    一.结构体与指针 1.结构体的高级初始化.结构体的销毁.结构体池的应用 2.特征: 1).为了避免含有指针成员的结构体指针的初始化复杂操作,将所有初始化动作使用函数封装: 2).封装函数主要实现内存的 ...

  7. Perl语言入门--5--散列、hash

    hash 一.关联数组的形式 %h=('a',1,'b',2);         a是key 1是value    b是key  2是value 以%开头,()为空散列 %h=('a'=>1,' ...

  8. robot upstart 问题

    1.启动后在记录文件发现左轮节点未启动: 因为左边的类未实例化,不会去订阅消息然后初始化 2.两个节点均可以启动后,发现启动后又死掉 因为在程序里有getenv(“HOME”)然后付给string,g ...

  9. linux下添加定时任务。

    这周要做一个定时增量更新Elasticsearch索引的功能,以前没有做过定时更新,所以请教了下同事,使用crontab添加linux下的定时任务. 一.linux下定时执行任务的方法 在linux中 ...

  10. DTrace Oracle Database

    http://d.hatena.ne.jp/yohei-a/20100515/1273954199 DTrace で Oracle Database のサーバー・プロセスをトレースしてみた Oracl ...