博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
集合(一) - ArrayList
阅读量:6593 次
发布时间:2019-06-24

本文共 2784 字,大约阅读时间需要 9 分钟。

一、层级关系

clipboard.png

二、初始化方式

(1)List
list = new ArrayList<>();public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

第一个结论:ArrayList底层是数组

第二个结论:若用无参构造器的方式实例化ArrayList,只是声明了数组,还未分配空间

(2)List
list = new ArrayList<>(10);public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); }}private static final Object[] EMPTY_ELEMENTDATA = {};

补充第二结论:若用有参构造器的方式实例化ArrayList且initialCapacity大于0,则既声明了数组,也分配了空间

三、基本方法的使用

add

  • 流程图

clipboard.png

  • 源码解析
public boolean add(E e) {    //校验数组容量,若空间不够则扩容复制生成一个新的数组    ensureCapacityInternal(size + 1);     //赋值    elementData[size++] = e;    return true;}private void ensureCapacityInternal(int minCapacity) {    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}/** * 若数组是通过无参构造器的方式实例化的话,返回的minCapacity为10,最后会通过grow方法复制生成一个大小为10的数组 * 若数组是通过有参构造器的方式实例化的话,返回的minCapacity为当前要操作的数组下标,不建议声明小于10的数组空间,因为这样前几次add都要去扩容复制生成一个新的数组 */private void ensureExplicitCapacity(int minCapacity) {    modCount++;    // overflow-conscious code    if (minCapacity - elementData.length > 0)    grow(minCapacity);}//扩容大小:原数组大小 + 原数组大小/2private void grow(int minCapacity) {    // overflow-conscious code    int oldCapacity = elementData.length;    int newCapacity = oldCapacity + (oldCapacity >> 1);    if (newCapacity - minCapacity < 0)    newCapacity = minCapacity;    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);}
  • 其它说明

    1. 初始化ArrayList时,不建议声明小于10的容量,因为这样前几次add都要去扩容复制生成一个新的数组
    2. Arrays.copyOf(T[] original, int newLength):该方法会创建一个新的数组

remove

  • 流程图

clipboard.png

  • 源码解析
public E remove(int index) {    //检查index是否 >= size,若大于则报数组越界异常    rangeCheck(index);    modCount++;    E oldValue = elementData(index);    int numMoved = size - index - 1;    if (numMoved > 0)    System.arraycopy(elementData, index+1, elementData, index,    numMoved);    elementData[--size] = null; // clear to let GC do its work    return oldValue;}
  • 其它说明

    1. System.arraycopy - 浅复制
public static void arraycopy(                             Object src,  //源数组                             int srcPos,  //源数组要复制的起始位置                             Object dest, //目标数组                             int destPos, //目的数组放置的起始位置                             int length   //复制长度                             )

四、补充

  • ArrayList是线程不安全的,表现在多线程下add和remove可能会发生数组越界
  • 不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁

转载地址:http://emcio.baihongyu.com/

你可能感兴趣的文章
Ajax技术细节
查看>>
nuxt.js部署vue应用到服务端过程
查看>>
删除数组中的指定元素 | JavaScript
查看>>
CSS3+JS实现静态圆形进度条【清晰、易懂】
查看>>
关于树形插件展示中数据结构转换的算法
查看>>
图片加载框架之Fresco
查看>>
高性能web建站规则(将js放在页面底部)
查看>>
Java EnumMap工作原理及实现
查看>>
阐述Spring框架中Bean的生命周期?
查看>>
注水、占坑、瞎掰:起底机器学习学术圈的那些“伪科学”
查看>>
大数据小视角1:从行存储到RCFile
查看>>
第18天:京东网页头部制作
查看>>
好消息:Dubbo & Spring Boot要来了
查看>>
面向对象封装的web服务器
查看>>
南开大学提出新物体分割评价指标,相比经典指标错误率降低 69.23%
查看>>
初创公司MindMaze研发情绪反应VR,让VR关怀你的喜怒哀乐
查看>>
绕开“陷阱“,阿里专家带你深入理解C++对象模型的特殊之处
查看>>
ElasticSearch
查看>>
9-51单片机ESP8266学习-AT指令(测试TCP服务器--51单片机程序配置8266,C#TCP客户端发信息给单片机控制小灯的亮灭)...
查看>>
香港设计师带来仿生机器人,其身体 70% 构造均由3D打印完成
查看>>