ArrayList特点:

ArrayList方法实现:

  扩容方法的实现:

    源码:

      

 private void ensureCapacityInternal(int minCapacity) {
//如果数组为默认大小,则扩大的容量为minCapacity和默认值两个值的较大者
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
} ensureExplicitCapacity(minCapacity);
}
 private void ensureExplicitCapacity(int minCapacity) {
modCount++; // overflow-conscious code
//如果要扩大的容量比当前的数组长度大,则对数组进行扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

     /**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//增加的容量为原来大小的一半
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果增加了一半的容量还比要扩容的数量小,则新数组的大小为要扩容的数量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果新数组的大小大于Integer.MAX_VALUE - 8,则进行判断
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);
} private static int hugeCapacity(int minCapacity) {
//如果minCapacity < 0,则容量值溢出
if (minCapacity < 0) // overflow
throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;//Integer.MAX_VALUE - 8
}

  clone方法分析:

    ArrayList中的clone()方法为浅克隆,克隆后的集合对象与原有的集合对象不是同一个对象(即,指向不同的内存空间),但是它们集合元素引用的对象都是相同的。

    源码:

      

 public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
//重新分配了一个链表,但是里面的元素是复制的引用(浅克隆)
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}

  示例程序:

    

ArrayList<String> list = new ArrayList<>();
//这样加入集合中时,引用的对象在常量池中
// list.add("dongfangbubai");
// String string = "dongfangbubai";
////这样加入集合中时,引用的对象堆中
String string = new String("dongfangbubai");
list.add(string);
list.add("shangshanruoshui"); ArrayList listClone = (ArrayList) list.clone();
System.out.println(listClone); String content = "dongfangbubai"; System.out.println(list.get(0).equals(content));
System.out.println(list.get(0) == content);
//克隆前后两个集合对应的元素所引用的都是同一个对象,true
System.out.println(list.get(0) == listClone.get(0));
//克隆前后两个集合是不同的集合,false
System.out.println(list == listClone);

  ArrayList迭代时用迭代器只能一次删除一个元素(在一个迭代循环里),否则会出现java.lang.IllegalStateException异常。从源码可以看出这一点。

  

 public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification(); try {
ArrayList.this.remove(lastRet); cursor = lastRet;
//进行一次删除操作时,随即就把lastRet置为一,每次迭代时就把迭代的元素索引赋个给astRet
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}

 

  

// 数据结构发生改变,和fail-fast机制有关,在使用迭代器过程中,只能通过迭代器的方法(比如迭代器中add,remove等),修改List的数据结构, // 如果使用List的方法(比如List中的add,remove等),修改List的数据结构,会抛出ConcurrentModificationException

  

fail-fast机制的实现

  

fail-fast机制也叫作”快速失败”机制,是java集合中的一种错误检测机制。

在对集合进行迭代过程中,除了迭代器可以对集合进行数据结构上进行修改(迭代器进行结构修改时不会增加modCount值),其他的对集合的数据结构进行修改,都会抛出ConcurrentModificationException错误。

这里,所谓的进行数据结构上进行修改,是指对存储的对象,进行add,set,remove操作,进而对数据发生改变。

ArrayList中,有个modCount的变量,每次进行add,set,remove等操作,都会执行modCount++。

在获取ArrayList的迭代器时,会将ArrayList中的modCount保存在迭代中,

每次执行add,set,remove等操作,都会执行一次检查,调用checkForComodification方法,对modCount进行比较。

如果迭代器中的modCount和List中的modCount不同,则抛出ConcurrentModificationException

 源码:源码中modCount在list中,

expectedModCount是在迭代时传入的modCount值,若迭代过程中list结构改变时,modCount会增加,以此迭代器1来判断迭代时list是否变化。

  

 final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}

ArrayList与vector比较:

  

java集合之深入分析ArrayList的更多相关文章

  1. Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  2. java集合系列之ArrayList源码分析

    java集合系列之ArrayList源码分析(基于jdk1.8) ArrayList简介 ArrayList时List接口的一个非常重要的实现子类,它的底层是通过动态数组实现的,因此它具备查询速度快, ...

  3. Java集合框架之ArrayList浅析

    Java集合框架之ArrayList浅析 一.ArrayList综述: 位于java.util包下的ArrayList是java集合框架的重要成员,它就是传说中的动态数组,用MSDN中的说法,就是Ar ...

  4. 【Java集合系列】---ArrayList

    开篇前言--ArrayList中的基本方法 前面的博文中,小编主要简单介绍java集合的总体架构,在接下来的博文中,小编将详细介绍里面的各个类,通过demo.对比,来对java集合类进行更加深入的理解 ...

  5. java集合系列之三(ArrayList)

    上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解ArrayLi ...

  6. java集合框架03——ArrayList和源码分析

    最近忙着替公司招人好久没写了,荒废了不好意思. 上一章学习了Collection的架构,并阅读了部分源码,这一章开始,我们将对Collection的具体实现进行详细学习.首先学习List.而Array ...

  7. Java——集合框架之ArrayList,LinkedList,迭代器Iterator

    概述--集合框架 Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(Java Collection ...

  8. Java集合框架(一)-ArrayList

    大佬理解->Java集合之ArrayList 1.ArrayList的特点 存放的元素有序 元素不唯一(可以重复) 随机访问快 插入删除元素慢 非线程安全 2.底层实现 底层初始化,使用一个Ob ...

  9. java集合 collection-list-ArrayList 去除ArrayList集合中的重复元素。

    import java.util.*; /* 去除ArrayList集合中的重复元素. */ class ArrayListTest { public static void sop(Object o ...

随机推荐

  1. matlab 常用集合相关的函数

    Matlab常用的集合相关的函数如下:     union(A,B)              %求集合A和集合B的并集     intersect(A,B)             %求集合A和集合 ...

  2. windows10下git一些问题

    windows10下安装git 找不到ssh解决办法 解决办法是: 输入下列命令,一路回车 $ ssh-keygen -t rsa -C “邮箱地址” 若执行ssh-add /path/to/xxx. ...

  3. struts2之form标签theme属性详解

    struts2中theme属性包括xhtml,html,simple,ajax .默认是xhtml theme:设置struts2标签的主题,默认为xhtml. theme=xhtml时:会默认额外生 ...

  4. wpa_supplicant下行接口浅析

    wpa_supplicant通过socket通信机制实现下行接口,与内核进行通信,获取信息或下发命令. 以下摘自http://blog.csdn.net/fxfzz/article/details/6 ...

  5. 我的Vscode配置

    "editor.fontSize": 17,//字体大小 "editor.wordWrap": "on",//软换行 "files ...

  6. LintCode-105.复制带随机指针的链表

    复制带随机指针的链表 给出一个链表,每个节点包含一个额外增加的随机指针可以指向链表中的任何节点或空的节点. 返回一个深拷贝的链表. 挑战 可否使用O(1)的空间 标签 哈希表 链表 优步 code / ...

  7. iOS- iOS 7 的后台多任务 (Multitasking) 对比之前的异同、具体机制、变化

    简单来说,这玩意是对开发者友好,但对设备不友好的(可能会偷偷摸摸地占用流量和电量).对用户来说,如果你带宽够,对发热不敏感的话,会得到更好的应用体验. 从 iOS 4 开始,应用就可以在退到后台后,继 ...

  8. 【APS.NET Core】- 应用程序Startup类介绍

    转自:https://www.cnblogs.com/stulzq/p/7845026.html Startup类配置服务和应用程序的请求管道. Startup 类 ASP.NET Core应用程序需 ...

  9. [C/C++] C/C++错题集

    1. 解析: A:在GCC下输出:0    在VC6.0下输出:1 B:在GCC下输出:段错误 (核心已转储)    在VC6.0下输出:已停止工作,出现了一个问题,导致程序停止正常工作. C:正常 ...

  10. openstack中间件message queue 与memcached环境部署

    为什么要安装中间件 组件间的通信使用的是REST API 而组件内部之间的通信则是使用的中间件 首先登陆openstack的官网查看官方文档 www.openstack.org 应为在部署一个架构之前 ...