java集合之深入分析ArrayList
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的更多相关文章
- Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- java集合系列之ArrayList源码分析
java集合系列之ArrayList源码分析(基于jdk1.8) ArrayList简介 ArrayList时List接口的一个非常重要的实现子类,它的底层是通过动态数组实现的,因此它具备查询速度快, ...
- Java集合框架之ArrayList浅析
Java集合框架之ArrayList浅析 一.ArrayList综述: 位于java.util包下的ArrayList是java集合框架的重要成员,它就是传说中的动态数组,用MSDN中的说法,就是Ar ...
- 【Java集合系列】---ArrayList
开篇前言--ArrayList中的基本方法 前面的博文中,小编主要简单介绍java集合的总体架构,在接下来的博文中,小编将详细介绍里面的各个类,通过demo.对比,来对java集合类进行更加深入的理解 ...
- java集合系列之三(ArrayList)
上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解ArrayLi ...
- java集合框架03——ArrayList和源码分析
最近忙着替公司招人好久没写了,荒废了不好意思. 上一章学习了Collection的架构,并阅读了部分源码,这一章开始,我们将对Collection的具体实现进行详细学习.首先学习List.而Array ...
- Java——集合框架之ArrayList,LinkedList,迭代器Iterator
概述--集合框架 Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(Java Collection ...
- Java集合框架(一)-ArrayList
大佬理解->Java集合之ArrayList 1.ArrayList的特点 存放的元素有序 元素不唯一(可以重复) 随机访问快 插入删除元素慢 非线程安全 2.底层实现 底层初始化,使用一个Ob ...
- java集合 collection-list-ArrayList 去除ArrayList集合中的重复元素。
import java.util.*; /* 去除ArrayList集合中的重复元素. */ class ArrayListTest { public static void sop(Object o ...
随机推荐
- tensorflow学习笔记(4)-学习率
tensorflow学习笔记(4)-学习率 首先学习率如下图 所以在实际运用中我们会使用指数衰减的学习率 在tf中有这样一个函数 tf.train.exponential_decay(learning ...
- 创新手机游戏《3L》开发点滴(1)——道具、物品、装备表设计
一.游戏物品/道具系统数据模型设计特点 为了让游戏更加的丰富,我们1201团队的新手机游戏设计了道具系统.于是丰富了游戏.取悦了玩家,哭了开发——道具/物品数据子系统是简单的.复杂的.不确定的: 简单 ...
- [C++] OOP - Virtual Functions and Abstract Base Classes
Ordinarily, if we do not use a function, we do not need to supply a definition of the function. Howe ...
- Martian Addition
In the 22nd Century, scientists have discovered intelligent residents live on the Mars. Martians are ...
- “Hello World!”团队第二次会议
今天是我们团队“hello world!”团队召开的第二次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时间 20 ...
- Python中对变量是否为None的判断
三种主要的写法有: 第一种:if X is None; 第二种:if not X: 当X为None, False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()这 ...
- 软工冲刺-Alpha 冲刺 (3/10)
队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 很胖,刚学,照猫画虎做了登录与注册界面. 展示GitHub ...
- Alpha 冲刺(3/10)
队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 协助后端界面的开发 搭建项目运行的服务器环境 ...
- BAT批处理(四)
网络命令 net use \\ip\ipc$ " " /user:" " 建立IPC空链接 net use \\ip\ipc$ "密码" / ...
- jconsole工具监控java运行情况
jconsole是jdk自带的工具.所以要先安装jdk 1.jconsole工具的路径: 通过which jconsole来查看 /usr/local/jdk1.7.0_79/bin/jconsol ...