1:数据结构:

transient Object[] elementData;  //说明内部维护的数据结构是一个Object[] 数组

成员属性:

private static final int DEFAULT_CAPACITY = 10;

private static final Object[] EMPTY_ELEMENTDATA = {};  //空数组

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //默认空数组

transient Object[] elementData;  //维护数组的引用

private int size;   //数组长度

2:构造方法:

public ArrayList() {

this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; //构造长度为0的Object[]  赋值给elementData,用于后面保存数据

}

3:主要方法的分析: add  get   remove  add(int index,Object o)

1)       add:  以添加第一个元素为例

public boolean add(E e) { e=”aa”

ensureCapacityInternal(size + 1);  // size=0

elementData[size++] = e;

return true;

}

private void ensureCapacityInternal(int minCapacity) {  // minCapacity=1

if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //第一个元素 true

minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); //取 DEFAULT_CAPACITY

}

ensureExplicitCapacity(minCapacity);

}

下面进入ensureExplicitCapacity 分析

private void ensureExplicitCapacity(int minCapacity) {

modCount++;

// overflow-conscious code

if (minCapacity - elementData.length > 0)  //10-0=10

grow(minCapacity);  //进入扩容的方法

}

以下是扩容的方法:

private void grow(int minCapacity) {  // minCapacity=10

// overflow-conscious code

int oldCapacity = elementData.length;  // oldCapacity=0

int newCapacity = oldCapacity + (oldCapacity >> 1);  //移位操作,移位后newCapacity=0

if (newCapacity - minCapacity < 0)   //0-10=-10

newCapacity = minCapacity;    // newCapacity=10

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); //将旧数组中的内容拷贝到新的数组中  并且将新的数组赋值给elementData

}

扩容机制:

int newCapacity = oldCapacity + (oldCapacity >> 1);  //将新数组扩容为原先数组的1.5倍长度

2):add(int index,Object o)方法分析

主要的实现方法如下:

public void add(int index, E element) {  // index1

rangeCheckForAdd(index);   //和add方法里的一直

ensureCapacityInternal(size + 1);  //和add方法里的一直

System.arraycopy(elementData, index, elementData, index + 1,

size - index);  //主要是这里实现的index后面元素的拷贝

elementData[index] = element;

size++;

}

下面分析这句代码实现的效果

System.arraycopy(elementData, index, elementData, index + 1,

size - index);

原始数组的结构和数据:

 
   

System.arraycopy方法执行后的数据结构
将 b2,b3 往后复制元素

 
   

最后将index处的元素赋值

elementData[index] = element;

这就是在具体索引进行add
的方法,往后的元素进行拷贝,导致消耗比较大

3):get方法:

public E get(int index) {

rangeCheck(index);   //检查数组是否越界

return
elementData(index); //返回数组的index 索引出的元素

}

Get 方法比较简单,就不做过多分析了

ArrayList 源码分析 基于jdk1.8:的更多相关文章

  1. HashMap 源码分析 基于jdk1.8分析

    HashMap 源码分析  基于jdk1.8分析 1:数据结构: transient Node<K,V>[] table;  //这里维护了一个 Node的数组结构: 下面看看Node的数 ...

  2. CopyOnWriteArrayList 源码分析 基于jdk1.8

    CopyOnWriteArrayList  源码分析: 1:成员属性: final transient ReentrantLock lock = new ReentrantLock();  //内部是 ...

  3. ArrayList 源码分析(JDK1.8)

    ArrayList简介  ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAccess ...

  4. ArrayList源码分析(JDK1.8)

    概述 ArrayList底层是基于数组实现的,并且支持动态扩容的动态数组(变长的集合类).ArrayList允许空值和重复的元素,当向ArrayList中添加元素数量大于其底层数组容量时,会通过扩容机 ...

  5. HashMap源码分析-基于JDK1.8

    hashMap数据结构 类注释 HashMap的几个重要的字段 hash和tableSizeFor方法 HashMap的数据结构 由上图可知,HashMap的基本数据结构是数组和单向链表或红黑树. 以 ...

  6. ArrayList的源码分析(基于jdk1.8)

    1.初始化 transient Object[] elementData; //实际存储元素的数组 private static final Object[] DEFAULTCAPACITY_EMPT ...

  7. LinkedList的源码分析(基于jdk1.8)

    1.初始化 public LinkedList() { } 并未开辟任何类似于数组一样的存储空间,那么链表是如何存储元素的呢? 2.Node类型 存储到链表中的元素会被封装为一个Node类型的结点.并 ...

  8. ArrayList源码解读(jdk1.8)

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

  9. ArrayList源码分析--jdk1.8

    ArrayList概述   1. ArrayList是可以动态扩容和动态删除冗余容量的索引序列,基于数组实现的集合.  2. ArrayList支持随机访问.克隆.序列化,元素有序且可以重复.  3. ...

随机推荐

  1. 数据解析模块BeautifulSoup简单使用

    一.准备环境: 1.准备测试页面test.html <html> <head> <title> The Dormouse's story </title> ...

  2. win10自动休眠解决方法

    win10使用外接显示器时,总是过2分钟自动睡眠. 这是系统无人值守时睡眠时间的设定,默认是两分钟. 解决方法: 1.运行注册表管理器,win+r ,输入regedit.exe 2.定位到HKEY_L ...

  3. 多版本切换python

    Python 安装包去官网自行下载: https://www.python.org/downloads/mac-osx/ Mac os 自带python, 但我记得是python2.7版本 在选择安装 ...

  4. Ansible配置执行远程主机的ssh端口号

    在线上的环境中,服务端的ssh会有进行变更的情况 例如:有些服务器的ssh端口号是 34567 等情况,那么该如何配置呢? 编辑 /etc/ansible/hosts [servers] 配置完毕后, ...

  5. springboot读取自定义properties配置文件方法

    1. 添加pom.xml依赖 <!-- springboot configuration依赖 --> <dependency> <groupId>org.sprin ...

  6. Windows Server 2016-Hyper-V Replica副本功能介绍

    Hyper-V副本是一种可用于复制虚拟机的功能,作为业务连续性解决方案的一部分.从Windows Server 2012中,Hyper-V角色引入了Hyper-V Replica作为虚拟机的内置复制机 ...

  7. SQLServer常用快捷键汇总

    菜单激活键盘快捷键 操作 SQL Server 2017 SQL Server 2008 R2 移到 SQL Server Management Studio 菜单栏 Alt Alt 激活工具组件的菜 ...

  8. 5.1 RDD编程

    一.RDD编程基础 1.创建 spark采用textFile()方法来从文件系统中加载数据创建RDD,该方法把文件的URL作为参数,这个URL可以是: 本地文件系统的地址 分布式文件系统HDFS的地址 ...

  9. Ubuntu下搭建Kubernetes集群(3)--k8s部署

    1. 关闭swap并关闭防火墙 首先,我们需要先关闭swap和防火墙,否则在安装Kubernetes时会导致不成功: # 临时关闭 swapoff -a # 编辑/etc/fstab,注释掉包含swa ...

  10. jmeter插件

    https://jmeter-plugins.org/install/Install/ plugins-manager.jar放到 lib/ext中,重启可以发现JMeter Plugins Mana ...