IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> android ArrayList 源码详解 -> 正文阅读

[移动开发]android ArrayList 源码详解

        ArrayList<String> list=new ArrayList<>();
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }


    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

初始化了elementData,就是一个object数组;

我们再执行:list.add("wod");源码如下:

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

我们的size没有初始化,那么这里就是0;即=1,我们看方法:

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

我们刚初始化的elementData=空数组,所以满足条件,执行里面的方法:

minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);

我们传进来的minCapcity=1,而

private static final int DEFAULT_CAPACITY = 10;

它们两者取比较大的数,肯定是10了,即minCapcity=10;往下走:ensureExplicitCapacity()
   protected transient int modCount = 0;
 
   private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

显然,我们的10-0是大于0,则执行grow()方法:

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    public static final int MAX_VALUE = 2147483647; // 0x7fffffff
   
    private 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);
    }
oldCapacity=0

0+0 >> 1 =0 即newCapacity=0

0-10<0,所以执行newCapacity = minCapacity=10;?

所以

newCapacity-MAX_ARRAY_SIZE肯定是小于0,不执行条件内的代码:
elementData = Arrays.copyOf(elementData, newCapacity);把elementData的数据复制到elementData,并且指定elementData的大小为10;

所以第一次添加数据时,会初始化一遍数据elementData,大小为10;

然后elementData[0]=object ; size++

第二次添加数据时,看看会发生什么:

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

这时,size=1;加一就是2,执行:ensureCapacityInternal(2)

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

elementData不是空数组了,则不走条件内的,直接走外面,ensureExplicitCapacity(2)

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

这里modCount++,第二次modCount=2了;

因为我们这里minCapacity=2,elementData的长度是10,所以2-10肯定是小于零,所以不走grow(),添加元素到这里就完成了

到这,我们总结一下:

1、当我们初始化new ArrayList() 时候,ArrayList会初始化了elementData,一个object数组;

2、当我们第一次list.add()的时候,ArrayList会先将elementData处理成一个长度为10的空数组,然后再将要放的对象,存放到下标为0的地方,同时size变量++;

我们刚在方法ensureExplicitCapacity()里面,

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

在什么时候,添加数据的时候,什么情况下会执行:grow(minCapacity);

肯定是满足条件(minCapacity - elementData.length > 0),什么情况下会满足呢,我们来看一看;

我们看到:minCapacity,它是表示size+1,size是表示我们添加过几条数据,就是在data数组里面,有多少条不为空,那size就是多少;当我们已经全部添加满的时候,也就是size=10了,即将要添加第11条数据的时候,则即:size+1,或者:10+1,这时我们的minCapacity=11;

那么,11-10肯定是大于0,则执行grow( 11 )方法;

我们继续看grow()方法:

    private 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);
    }

整理如下:

minCapacity=11,(是我们传过来的参数)

oldCapacity=10;

newCapacity=10 + (10 >> 1)=10+ 5;(>> 1 左移一位,相当于除以2,右移一位相当于乘以2)
           =15


if(15-11<0){

    4<0,肯定不成立,即不满足条件,不执行
}

if (15 - MAX_ARRAY_SIZE > 0){
MAX_ARRAY_SIZE是一个很大 的值,15减一个大数,肯定小于0,则不满足条件,不执行
}

最后执行:

elementData = Arrays.copyOf(elementData, newCapacity);

最后:elementData[size++] = e;
即先执行size++

再:elementData[11] = e

所以到这,我们的添加数组,就全部结束啦;我们再总结一下:

当我们要添加大于数组长度的数据时,ArrayList会记性扩容,扩容后的数组长度为:原数据长度+二分之一原数组长度,这么说,不简便,即:扩容后的数组长度为原来数组的1.5倍;

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:41:20  更:2022-02-28 15:44:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 16:38:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码