相信对于使用过Java的人来说,ArrayList这个类大家一定不会陌生。

数据结构课上讲过,

Array是数组,它能根据下标直接找到相应的地址,所以索引速度很快,但是唯一的缺点是不能动态改变数组的长度,复杂度O(1)。

而List就是链表,它搜索相应地址都只能从链表头部一个一个找下去,直至找到对应的地址才停止,相比于数组来说,搜索速度肯定是慢的,但是有点是能动态的增删节点,复杂度O(n)。

而Java中这个ArrayList到底是什么东西呢?

先上代码,我们平时使用ArrayList一般这样使用:

public class ArrayListTest {

    public static void main( String[] args ) {
List<Integer> list = new ArrayList<Integer>();
list.add( );
list.add( );
list.get( );
list.remove( );
}
}

好,现在来解释每一步操作jdk做的事:

先看new ArrayList<>()初始化,

    public ArrayList(int initialCapacity) {
super();
if (initialCapacity < )
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
} /**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this();
}

很明显,如果初始化不指定capacity的话,默认初始化数组大小就是10。

其实细心发现,在重载的构造函数中,

this.elementData = new Object[initialCapacity];

这行代码暴露了ArrayList的本质,其实就是一个数组。

OK,现在我们拥有了一个长度为10的数组对象,现在我们执行add操作,看jdk操作

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

1.首先,暂且不理会ensureCapacityInternal()方法做的事,直接看【elementData[size++]=e】这行代码,显然地,是在elementData对象的size索引位置指向新元素,问题来了,万一size已经超出了当前数组的最大长度(假设是在第11个位置放置新元素),怎么办?

这里就要看ensureCapacityInternal方法了。

    private void ensureCapacityInternal(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}

这里可以很清楚地看出,

minCapacity - elementData.length > 0

这行代码检查了新增的元素位置是否超出了当前数组对象的最大长度,基于上面的假设,此判断是成立的,所以需要继续往下看,看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);
}

看第二行代码,newCapacity = oldCapacity + oldCapacity / 2;
就是说每次当发现当前数组长度不足时,每次增加的步长是【0.5倍的当前长度】。
Ps.注意这里有一个坑,假如增加长度后超出了Max_ARRAY_SIZE(jdk定义为maxIntValue-8),直接返回MaxIntValue。 最后就是调用Arrays.copyOf方法了,里面主要调用的是System.arrayCopy方法,是一个JNI调用,有兴趣的同学可以去JDk官网看底层的实现,这里就不多累赘了。 --------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------

接着来看看remove方法。
    public E remove(int index) {
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; // Let gc do its work return oldValue;
}
remove就比较简单了,它的原理就是找到要删除的下标,假设数组[1,2,3,4,5]你要删除3,jdk的做法就是把[1,2]和[4,5]数组复制到原数组,形成新数组[1,2,4,5,5],
然后执行elementData[--Size]防止内存泄露,完毕~

总结:
ArrayList就是一个通过申请新内存来扩容的数组!

【Java集合类】ArrayList详解 (JDK7)的更多相关文章

  1. Java集合类的详解与应用

    Java集合类的详解与应用 集合简介: 1.定义:可以同时存储不同类型的数据 他的存储空间会随着数据的增大而增大 2.缺点:只能存储引用数据类型 3.优点:更加合理的利用空间,封装了更多的方法,用起来 ...

  2. java集合类,详解

    集合详解 1.1HashSet HashSet是Set接口的一个子类,主要的特点是:里面不能存放重复元素,而且采用散列的存储方法,所以没有顺序.这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致 ...

  3. Java.util.ArrayList详解

    java.util.ArrayList就是传说中的动态数组. 继承了关系,有此可看出ArrayList与list的collection的关系 public class ArrayList<E&g ...

  4. Java 8 ArrayList 详解

    GitHub Page: http://blog.cloudli.top/posts/Java-ArrayList/ ArrayList 继承于 AbstractList ,实现了 List.Rand ...

  5. java集合类图详解

  6. [转载]Java迭代器(iterator详解以及和for循环的区别)

    Java迭代器(iterator详解以及和for循环的区别) 觉得有用的话,欢迎一起讨论相互学习~[Follow] 转载自 https://blog.csdn.net/Jae_Wang/article ...

  7. ArrayList详解-源码分析

    ArrayList详解-源码分析 1. 概述 在平时的开发中,用到最多的集合应该就是ArrayList了,本篇文章将结合源代码来学习ArrayList. ArrayList是基于数组实现的集合列表 支 ...

  8. 转:Java HashMap实现详解

    Java HashMap实现详解 转:http://beyond99.blog.51cto.com/1469451/429789 1.    HashMap概述:    HashMap是基于哈希表的M ...

  9. java集合框架详解

    java集合框架详解 一.Collection和Collections直接的区别 Collection是在java.util包下面的接口,是集合框架层次的父接口.常用的继承该接口的有list和set. ...

随机推荐

  1. 完美解决夏天电脑cpu发烫问题

    最近有朋友跟我反馈,说苹果电脑虽然好用,但是一直有一个问题困扰着他,就是电脑散热的问题.每到夏天的时候,电脑运转之后就会发烫,用的特别的不舒服. 相信用电脑的都会有这样的感受吧,更加相信你们都用过以下 ...

  2. phpcms 杂乱总结

    1.根据catid 获取 栏目名称 $CATEGORYS = getcache('category_content_'.$siteid,'commons'); $name = {$CATEGORYS[ ...

  3. #图# #dijkstra# ----- OpenJudge 726:ROADS

    OpenJudge 726:ROADS 总时间限制: 1000ms内存限制: 65536kB 描述 N cities named with numbers 1 ... N are connected ...

  4. 内存快照排查OOM,加密时错误方法指定provider方式错误引起的OOM

    写在前面: 最近开始总结内存方面的东西,已经总结以前遇到的一些内存案例分享下,接下来还有几篇,然后是进程/线程相关的,逐渐形成我的知识体系树 如果你有兴趣,可以文章末尾的公众号二维码一起梳理这些信息. ...

  5. MVC + Vue.js 初体验(实现表单操作)

    Vuejs http://cn.vuejs.org/ Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的 ...

  6. asp.net客户端IP跟踪

    /// <summary> /// 获取客户端IP地址(无视代理) /// </summary> /// <returns>若失败则返回回送地址</retur ...

  7. spring-dwr注解整合

    注解配置 1.web.xml 只需将DwrServlet换为DwrSpringServlet(包名不同) 2.dwr类 3.applicationContext.xml 4.annotationCon ...

  8. Jmeter生成html格式测试报告

    使用jmeter进行性能测试,运行完毕后生成html格式的测试报告,需要进行如下操作: 1.在C:\apache-jmeter-3.0\bin文件夹下的user.properties文本中添加如下信息 ...

  9. .net学习网站汇总

    http://chs.gotdotnet.com/quickstart/简介:本站点是微软.NET技术的快速入门网站,我们不必再安装.NET Framework中的快速入门示例程序,直接在网上查看此示 ...

  10. jQuery动态生成不规则表格前后端

    一.需求:有这么一张表 前四个属性当作联合主键 需要把该表所有的行在前端以表格形式显示出来,要求activityId相同时合并成一行,activityCode相同时,合并一行,activityVers ...