热门标签 | 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*(),这样的方法


推荐阅读
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Day2列表、字典、集合操作详解
    本文详细介绍了列表、字典、集合的操作方法,包括定义列表、访问列表元素、字符串操作、字典操作、集合操作、文件操作、字符编码与转码等内容。内容详实,适合初学者参考。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
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社区 版权所有