以前学java基础的时候 看过ArrayList的扩容机制

实现原理是下面这样 当时做的笔记

ArrayList扩容机制 在jdk1.7前是 *3/2+1 在jdk1.7开始就是 old+(old>>1) ->1.5倍扩容

然后今天看内存优化的时候 突然看到这个 就看了看android的ArrayList的源码

一看吓一跳 原来和JDK里面的算法有点不一样

然后马上进入JDK里面的源码 看了ArrayList 版本 1.8.0

JDK 1.8 ArrayList源码

默认容量是10 初始化是10

private static final int DEFAULT_CAPACITY = 10;

直接传入 size初始化不会扩容 就直接创建一个新的数组

Paste_Image.png

直接看Add方法 在add的时候 如果容量不够 肯定会扩容

Paste_Image.png

Paste_Image.png

发现这个函数

Paste_Image.png

最后发现 实现代码在这里

来分析一下 实现方式

Paste_Image.png

Paste_Image.png

所以可以总结 JDK里面实现方式是 先1.5倍扩容 如果扩容之后还是小于现在需要的 就设置size为需要的

然后得到新的size 拿到新的size去和最大的MAX_Array_SIZE去比较 按照他的规则实现

最后创建一个新的数组 把原来的加载新的前面 后面就是空的

再看看Android内部的实现

初始大小是12 还说什么 12要好点 凑个团圆吗?

Paste_Image.png

/**

* The minimum amount by which the capacity of an ArrayList will increase.

* This tuning parameter controls a time-space tradeoff. This value (12)

* gives empirically good results and is arguably consistent with the

* RI's specified default initial capacity of 10: instead of 10, we start

* with 0 (sans allocation) and jump to 12.

*/

private static final int MIN_CAPACITY_INCREMENT = 12;

同样的先看 add方法

Paste_Image.png

再看看addAll方法 观察 Android在这里做了处理 在addAll的时候 有新的扩容机制

Paste_Image.png

发现还是和上面add的时候一样 但是进去的size不同了

Paste_Image.png

Paste_Image.png

最大的不同来了 Android是在old+newPartSize=newSize 之后 对newSize扩容 而JDK 不是 JDK是newSize=old+old>>2 在比较newSize与需要的Size的大小

所以这里得出总结

JDK 中 ArrayList的扩容机制 需要的size

1 新的Size1.5倍扩容 newSize=old+old>>1

2 发现扩容之后 还是不够 就设置为 需要的Size 在经过一次判断 大于设置的最大就给设置为Int最大值 否则就是int最大值-8(也就是默认设置的最大值)

Android实现原理

1 newSize=oldSize+newPartSize 然后对这个新的newSize进行 <12就设置为12 否则就 1.5倍扩容

举个例子

oldSzie=20 addAll(newPart) newPartSize=50;

JDK 中 old+old>>1=35 35<70 newSize=70 ---> Size=70

Android中

20+50 ---->70 70-1=69>6--->69+34=103 size=103

看下测试数据

Android版本的

Paste_Image.png

JDK的 与 想法一致

Paste_Image.png

oldSzie=20 addAll(newPart) newPartSize=10;

for (int i = 0; i < 20; i++) {

data.add("Daemon" + i);

Class d = data.getClass();

/*

* 得到类中的所有属性集合

*/

try {

Field fs = d.getDeclaredField("elementData");

fs.setAccessible(true);

System.out.println("elementData.size " +i+"---"+ ((Object[])fs.get(data)).length);

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

}

前20个加载完 初始化10 第11个进来的时候1.5被扩容 15 第16个进来扩容22 20个加载完毕 然后 加载10个 扩容 33 最后为33

当addAll(10) 的时候 oldSize+oldSize/2=33 所以在33之前 都能加载进去 不会扩大

JDK 实现

Paste_Image.png

Android 版本的 初始化 12 第13个进来扩容1.5倍 18 第19个进来扩容1.5 27

以后addAll因为算大不一样是 size+newpartsize 即 20+10-1扩容 也就是 43正确

Paste_Image.png

下班了 在路上手机码完

图片发自简书App

android动态扩容数组,ArrayList 扩容 Android Java 真的不一样相关推荐

  1. android 动态生成多个textview,android – 如何将多个TextView动态添加到main.xml中的定义LinearLayout...

    我知道可以将一些布局(如Button和TextView)添加到LinearLayout中.我想根据for循环的条件创建多个TextView. 我用自己的方式尝试过,但我无法创建它.有谁知道如何创建它? ...

  2. android 动态获取权限有哪些,Android 6.0+ 动态获取权限

    Android 6.0+ 动态获取权限 这里有一个现成的库,可以直接拿来用.方便简单 1.向app下的gradle添加依赖: dependencies{ // android 6.0+ 动态获取权限 ...

  3. android动态添加布局属性 layoutparmas,Android 代码动态布局 LayoutParams 使用

    先来看一个简单的布局,先用xml写 xmlns:tools="http://schemas.android.com/tools" android:layout_width=&quo ...

  4. android动态申请悬浮框权限,Android中代码动态判断是否开启悬浮窗权限和申请悬浮窗权限...

    原因 在某些机型上居然后出现permission denied for window type 2038错误: E/AndroidRuntime: FATAL EXCEPTION: main Proc ...

  5. android 动态设置style属性值,android中的style属性值,以及一些预定义样式

    Android平台定义的主题样式:android:theme="@android:style/Theme.Dialog" // 将一个Activity显示为对话框模式 androi ...

  6. android动态设置maxWidth,如何使用android:maxWidth?

    I want to set a maximum width of an edit box. 在你的例子中: android:layout_width="fill_parent" a ...

  7. android动态添加数组中,Android动态数组

    我正在通过Android Pull Parser技术解析XML文件.首先,看看下面的XML文件: hello xyz abc def 考虑一下我正在解析上面的文件.现在,我的问题是我想为名称和地址创建 ...

  8. android动态交换控件位置,Android DynamicGrid实现拖曳交换位置功能

    Android DynamicGrid是一个第三方开源项目,DynamicGrid在github上的项目主页是:DynamicGrid 它实现在一个网格布局内,拖曳任意子view实现动态的交换位置,这 ...

  9. android动态申请权限第三方库,Android 关于动态申请权限

    第一种方式:引入三方库,利用第三方申请权限 1.引入三方库: api'com.tbruyelle.rxpermissions2:rxpermissions:0.9.3@aar' 2.调用(当然你需要什 ...

最新文章

  1. js new 运算符到底做了什么?
  2. 【直播预告】7月18日3D游戏引擎免费公开课答疑,參与送C币!
  3. 松本行弘为什么要开发Ruby
  4. 登录form php一个页面跳转页面,form表单页面跳转方式提交练习
  5. 提高SQLITE 大数据量操作效率的方法
  6. PC软件开发技术之三:C#操作SQLite数据库
  7. 橡皮擦的英语_从填字涂鸦到英语启蒙,家长口中的儿童版“秘密花园”涂色游戏测评【玩具测评】...
  8. 作者:曾琛(1987-),女,就职于中国科学院计算技术研究所。
  9. 什么是程序员的优良品质
  10. 360浏览器升级_360安全卫士下载|360安全卫士 12.0 最新版
  11. 没错!Python 杀死了 Excel!
  12. MaxCompute 2.0 生态开放之路及最新发展
  13. 数据计算 统计学案例_数据分析适合什么专业?
  14. 游戏开发中的那点英语
  15. matlab进化树的下载,Dendroscope(进化树显示分析软件)
  16. opencv实现图像的边缘提取
  17. 计算机颜色管理器,系统颜色管理完全攻略
  18. 苹果虚拟home键_苹果手机几个实用小技巧,相见恨晚,快试试你的手机!
  19. 《Adobe Illustrator CS6中文版经典教程(彩色版)》—第0课0.15节使用“外观”面板与效果...
  20. PTA 7-14 电话聊天狂人(25 分)map的应用

热门文章

  1. Jupyter Lab 十大高生产力插件
  2. SQL Server 连接字符串和身份验证
  3. ftp工具,ftp工具专业版
  4. ftp下载工具绿色版,网络上难找的绿色版ftp下载工具
  5. Windows连接ssh时 Permissions for ‘.pem‘ are too open解决方法
  6. php mpm,ubuntu切换为apache+php-fpm+mpm_event
  7. eclipes 快捷键操作:
  8. python 对excel的函数操作_自动化报表(3)
  9. php 必须实现方法,php – 错误:类必须声明为抽象或实现其余的方法
  10. 如何做推广?利用今日头条吸引大量精准粉丝