源码分析:
集合的Collection接口,LIst接口我们都已经学习完毕了,这里我们来接口的实现类de 源代码
在jdk1.7和jdk1.8中源码是有点区别的,这里先看1.7版本的
1.7版本
看1.7版本之前需要先把idea中的jdk版本换成1.7的版本
【1】在idea中切换jdk 的方法
【2】ArrayList实现List接口的失误
创建集合的创始人承认了此失误,但是后续也没有更改。
【3】底层重要的属性
在jdk1.7中,在调用构造器的时候给底层数组elementData初始化,数组初始化长度为10:
这里画了一个对应的内存
集合有了以后,我们就可以往集合中放数据了,调用的是add()方法。在提示中我们可以看到add中的数据类型是object的类型,那么如果是object的类型,那么我们就可以放“字符串”、“integer类型”、“double类型”等的引用类型数据均可
ArrayList al = new ArrayList();
System.out.println(al.add("abc"));
System.out.println(al.add("def"));
通过源码可以看到这个返回值是个boolean类型的
每次在集合中添加一个数据之后,底层代码的size就是加1,如果假设这个底层数组大小是10,那么应该怎么处理呢,继续看源码来分析
如果数组满了以后就会执行上述代码的
ensure CapacityIUnternal (size + 1);
开始进行扩容,原数组的1.5倍
这里的扩容本质,和原理都写在了图中。
【1.7版本总结】
1.7版本的源码到此就结束了,总结一句话:
为底层数组,在调用构造器的时候,数组的长度为10,扩容的时候扩展到原来的1.5倍。
1.8版本源码
【1】 jdk1.8底层依旧是Object类型的数组,size数组中有效程度:
【2】ArrayList al = new ArrayList();调用空构造器
在jdk1.8中,在调用空构造器的时候,底层elementData数组的
初始化为空数组{},这就是1.7和1.8的区别
【3】调用add方法
【1.8版本总结】
底层仍然是个数组,但是在调用构造器的时候,底层的数组为 {空},在调用add的方法后,底层的数组才重新的赋值为新数组,新数组的长度为10
这样的好处就是就是节省了内存空间,在add后才创建了长度为10的数组。
这样源码就分析完成了,下面我们来看看Vector。
vector虽然说逐渐被淘汰了,但是看了面试题,还是有人会问,这里分析一下vetcot的源码
vetcor源码分析
【1】底层Object数组,int类型属性表示数组中的有效长度
【2】调用构造器
【3】add方法
这里有个小区别,在学过线程肯定都能发现:
【4】完善图
底层都是数组,那么我们来看看优缺点
数组有点:查询效率高。 特点:数据可重复
数组缺点:删除、增加元素效率低