热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ArrayList深度解析

ArrayList底层学习底层知识底层使用的是数组的数据结构属性默认的初始化容量privatestaticfinalintDEFAULT_CAPACITY10;一个空的

ArrayList 底层学习


底层知识

底层使用的是数组的数据结构


属性

//默认的初始化容量
private static final int DEFAULT_CAPACITY = 10;
//一个空的Object数组的实例(当使用有参构造器public ArrayList(int initialCapacity)时候自定义容量为0时候赋值给elementData)
private static final Object[] EMPTY_ELEMENTDATA = {};
//和上面一样是个空数组实例(当使用默认无参构造器时赋值给elementData)
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//真正的存放数组的数组
transient Object[] elementData;
//数组的长度
private int size;

构造器

public ArrayList(int initialCapacity) {if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];//如果>0则直接立马给数组分配空间} else if (initialCapacity == 0) {//如果输入参数为0,那么就赋值一个空数组this.elementData = EMPTY_ELEMENTDATA;} else {throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);}}public ArrayList() {//可在属性中查看this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}

从这两个构造器中我们发现,如果我们给它一个整型参数且>0,那么会立马给elementData数组分配空间,如果为0则不管。但是如果调用无参构造器的时候我们发现他并没有分配空间,而是将它指向默认的空的elementData对象,但是并没有立马给他分配空间


newCapacity(int minCapacity)

//这个是将数组进行一个扩容操作,
private int newCapacity(int minCapacity) {//保存旧数组的容量int oldCapacity = elementData.length;//新数组的大小为旧数组+旧数组右移一位的和,相当于是扩大为原来1.5倍(newCapacity为扩容后的容量)int newCapacity = oldCapacity + (oldCapacity >> 1); //下面判断为真的例子/*当我们使用默认构造器时候,我们的elementData对象是一个空数组,那么oldCapacity = elementData.length = 0那么 newCapacity = oldCapacity + (oldCapacity >> 1) = 0minCapacity = size + 1 ,此时size = 0,minCapacity = 1 newCapacity - minCapacity = -1 <= 0*/if (newCapacity - minCapacity <= 0) {//进入下面的判断分支说明使用的是默认构造器if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)return Math.max(DEFAULT_CAPACITY, minCapacity);// overflow(内存溢出)if (minCapacity < 0) throw new OutOfMemoryError();//如果使用有参构造器并且自定义capacity定义为0,就会使用下面的return,即返回1//(非常不建议这样,因为这样会导致数组不停的扩容,影响性能)return minCapacity;}//这是正常的扩容容量,return (newCapacity - MAX_ARRAY_SIZE <= 0) //判断新容量不超过最大容量的三目运算? newCapacity //为真: hugeCapacity(minCapacity); //为假(分析可以看下面)
}private static int hugeCapacity(int minCapacity) {//内存已经用完了if (minCapacity < 0) throw new OutOfMemoryError();//minCapacity已经超过定义的最大数组长度的三目运算return (minCapacity > MAX_ARRAY_SIZE)? Integer.MAX_VALUE //为真(设置为最大的Int的最大数值容量): MAX_ARRAY_SIZE; //为假(设置为定义的最大容量)}

add()方法

//这个是扩容时调用的grow方法private Object[] grow(int minCapacity) {return elementData = Arrays.copyOf(elementData,//这里是将旧数组的信息复制到新数组中newCapacity(minCapacity));}private Object[] grow() {return grow(size + 1);}private void add(E e, Object[] elementData, int s) {//这里的s传入的基本都是size//当size的长度达到了数组的定义的长度时候就需要会进行扩容if (s == elementData.length)elementData = grow(); //这里将数据保存进数组中,并且将size + 1 elementData[s] = e; size = s + 1;}//平时调用的最多的方法public boolean add(E e) {//这个就是继续数组被更改的次数modCount++;//调用私有方法addObject[] elementData;if ((s = size) == (elementData = this.elementData).length)elementData = grow();System.arraycopy(elementData, index,elementData, index + 1,s - index);elementData[index] = element;size = s + 1;}//-----------------------------下面为按下标进行一个插入操作---------------------------------------------private void rangeCheckForAdd(int index) {if (index > size || index < 0)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*这个方法我们可以明确的发现说明:只能插入在list的size以内的数据,相当于只能替换时候使用该方法,平时的插入还是以add(E e)为主*/public void add(int index, E element) {//对该下标进行一个判断,看看是否超过size或者index <0 rangeCheckForAdd(index);//对数组修改操作 + 1modCount++;final int s;Object[] elementData;//和一个参数的add()方法一样,判断需不需要进行一个扩容操作if ((s = size) == (elementData = this.elementData).length)elementData = grow();System.arraycopy(elementData, index,elementData, index + 1,s - index);//将数据存储到数组中elementData[index] = element;//size + 1size = s + 1;}

Vector(线程安全)

底层也是使用的暴力加锁方法,直接使用synchronized修饰


如何选择线程安全的集合

1.可以选择线程安全的类,例如Vector,HashTable,ConcurrentHashMap

2.可以使用Collections.synchronized*(),这样的方法


推荐阅读
author-avatar
郭先2502898821_918
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有