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. [leetcode-667-Beautiful Arrangement II]

    Given two integers n and k, you need to construct a list which contains n different positive integer ...

  2. 词频统计 SPEC 20170914 1 1 1 1 1

    功能1 小文件输入,为表明程序能跑,结果真实而不是迫害老五,请他亲自键盘在控制台下输入命令. #include<stdio.h> #include<string.h> #inc ...

  3. TCP系列07—连接管理—6、TCP连接管理的状态机

            经过前面对TCP连接管理的介绍,我们本小节通过TCP连接管理的状态机来总结一下看看TCP连接的状态变化 一.TCP状态机整体状态转换图(截取自第二版TCPIP详解) 二.TCP连接建立 ...

  4. 原生js 自定义confirm

    本文参考博客园另一篇文章:https://www.cnblogs.com/hzj680539/p/5374052.html,在此感谢. 在实际开发当中,考虑到原生js组件,包括alert.confir ...

  5. Linux服务器记录并查询历史操作记录

    Linux服务器在使用过程中,经常会有除自己之外的其他人员使用.并不是每个人都对Linux服务器特别熟悉,难免会有一些操作导致服务器报错. 因此,监控Linux服务器的操作并记录下来,是非常有必要的! ...

  6. AMH面板命令操作大全

    LNMP面板 - AMH 命令使用nginx篇 » SSH Nginx1) 有步骤提示操作: ssh执行命令: amh nginx然后选择对应选项进行操作. 2) 或直接操作: 启动Nginx: am ...

  7. java 基础--数组--004

    1,数组定义格式 String[] aa; String aa[];2,二位数组的定义格式1 String aa[][] = new String[m][n]; String[] aa[] = new ...

  8. Angular-Cli中引用第三方库

    最近在学习angular(AngularJS 2),根据教程使用angular-cli新建项目, 然而在添加JQuery和Bootstrap第三方库时遇到了问题... 初试 我最初的想法是直接将相对路 ...

  9. 三次握手 四次握手 与socket函数的关系

    “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...

  10. 一日一句 SQL [持续更新] MySQL + Oracle

    1 . group by 和 having字句: group by是根据列值对数据进行分组, having子句用于对分组的数据进行过滤. [ having 针对的对象是分好的组] eg: employ ...