浅析ArrayList的内部实现
来源:互联网 发布:新手开淘宝店怎么装修 编辑:程序博客网 时间:2024/05/16 15:13
ArrayList的特性:可以自由扩展,存储任意多个数字,弥补了数组的定长的缺陷,但是他的内部还是数组!为什么ArrayList可以自由扩展? 下面我们用代码来演示下ArrayList的内部实现!
首先我们定义一个MyArrayList,既然是集合,集合的内部实现都是数组,我们定义一个MyArrayList里面包含一个Object类型的数组和一个int 类型的size。size是用来存储数组中存储了多少个Object!
publicclass MyArrayList {
Object []arr=new Object[2]; //定义一个数组
intsize=0; //存入了多少数到数组里面的记录!
(数组里面有多少个数)当记录数等于数组的长度时就需要扩容
}
这样我们自己的MyArrayList就定义好了,在ArrayList中有添加数,在指定位置添加数,根据索引查询,根据索引删除,删除指定对象等方法,用代码来实现:
首先定义一个添加的方法add(Object object); 我们只需要将传进来的object添加到上面定义好的arr的数组中,但是数组的长度只有2个,当我们添加第三个object的时候,就会越界,下面我们要做的是将arr数组的长度增加!如何做了?
代码实现如下:
/*添加数据,判断扩容*/
publicvoid add(Object num){
if(arr.length==size){
Object[] temp = new Object[arr.length*3/2+1];
System.arraycopy(arr, 0, temp, 0,size);
arr=temp;
}
arr[size++]=num; //每进一个数就要将记录数++
}
下面我们来看下代码的实现
当我们发现数组的长度等于数组中的记录数的时候,我们知道,数组已经装满了!如果在添加的话就会越界,这时我们就new一个临时数组temp出来,长度比原来数组长度大就行了,然后我们把arr数组里面的数按添加位置,复制到temp中就行了,我们可以使用for循环一个一个的去移,那样速度会慢一点(但数大的时候区别大一些,代码中的方法为源码中的方法,我们借鉴下),我们就是用System.arraycope方法将arr数组按添加位置添加临时数组temp数组中,arraycope方法中五个参数的意思分别是:源(要copy哪个数组,以arr和temp为例)、从arr的0个位置开始copy、copy到temp数组、copy到temp的0个位置、copy多少个长度! 整个意思就是 我们将arr数组中的第0个位置开始一直copy数组中的记录数size个数 copy到temp中从第0个位置开始放置!这样我们的temp数据就比arr数组要大,然后再temp数组整体复制给arr数组就达到了扩容的目的!好了我们第一个方法add(Object object) 方法成功!
现在是不是迫不及待的测试下自己的MyArrayList的方法add(Object object)是否成功,我们就写一个get(int index)方法就行!在get(int index)方法中我们要做的就是将arr数组中的数据按index索引返回就行。
代码示例:
public Object get(int index){
returnarr[index];
}
呵呵! 就这么简单!我们定义好了一个MyArrayList集合!
然后就是指定索引位置添加数据了!现在我们应该有一个思路,我们的MyArrayList就是一个数组,跟数组不同的就是一个扩容问题,我们把扩容处理好了,就是在对数组操作!
我们还是先定义一个方法add(Object object)方法重载的方法,add(int index,Object object)方法,要做的三件事,首先是判断数组是否需要扩容,然后是将指定位置后的object整体往后移一位,最后就是将要添加的object添加到指定的index位置了!
代码如下:publicvoid add(int index,Object object){
/*传递过来的索引我们首先要判断是否大于数组的长度
*小于我们就加!否则越界
*我们还要判断一点的是他什么时候扩容
*/
if(index<arr.length){
if(size==arr.length){
Object []temp=new Object[arr.length*3/2+1];
System.arraycopy(arr, 0, temp, 0,size);
arr=temp;
}
System.arraycopy(arr, index,arr, index+1,size-index);
arr[index]=object;
size++;
}
}
分析一下代码上面一个arraycopy是扩容,下面的一个arraycopy是移位,意思是我们将arr数组从传进来的索引位置开始移,还是移到arr数组的传进来的索引位置的后一位(加1就是后一位),这样传进来的索引位置就空出来了,我们在把传进来的object赋值给传进来指定索引位置的arr数组就搞定了!
测试一下,依然成功!我们已经完成了MyArrayList的三个方法!下面我们在来写remove方法,同样remove方法也是一个重载!remove(int index)是从索引删除,remove(Object object)
这两个方法似乎有冲突,因为int 也继承Object 当我们传一个int进去时会自动找到int而不是Object(相当于一种就近原则,找他的子类,而不会找父类)!
我们先来写从指定索引删除吧!删除后我们就不管他是否减容吧!我们先来看下remove(int index)这个方法吧!我们要传一个索引进来然后删除!删除之后我们在将index后的object向前移一位就行了!当然要将记录数减1就行了!
publicvoid remove(int index){
/*先删除指定索引的值,然后移位*/
if(index<size){ //要有那个数存在才能删除
System.arraycopy(arr, index+1,arr, index,size-index-1);
size--;
}
}
上面的方法我们同样用的是arraycopy,我们只需要将arr中的index后一个位开始移起,移到arr的index位,移动为index后面的位数就行了! 相当于我们直接把arr的index给覆盖掉就行!
下面在写remove(Object object)方法,想一下,我们已经能够通过索引删除元素了,我们只要找到传进来的object的索引然后传进去就KO了
看下代码
publicvoid remove(Object object){
for(int i=0;i<arr.length;i++){
if(arr[i].equals(object)){
remove(i); //调用写好的通过索引删除
}
}
}
我们通过循环找到索引后传到remove(int index)里面就达到了删除的目的!
关于ArrayList里面的一些简单方法就完成了!似乎没有想象中的那么难!
下面我们看下关于ArrayList内部的实现的一些方法!
首先他定义的一个add(Object object)方法吧!
publicboolean add(E o) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = o;
returntrue;
}
publicvoidensureCapacity(int minCapacity) {
modCount++;
int oldCapacity =elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = (E[])new Object[newCapacity];
System.arraycopy(oldData, 0, elementData, 0, size);
}
}
同样也是不够用就扩容!在new数组的时候 前面加上了(E[])从List继承而来,可以支持泛型!
Add(int index,Object object)
publicvoidadd(int index, E element) {
if (index >size || index < 0)
thrownew IndexOutOfBoundsException( "Index: "+index+", Size: "+size);
ensureCapacity(size+1); // Increments modCount!!
System.arraycopy(elementData, index,elementData, index + 1, size - index);
elementData[index] = element;
size++;
}
当传进来的添加的指定位置的索引大于数组的记录数或是小于0将抛出异常!
否则调用扩容,然后就是移位!
- 浅析ArrayList的内部实现
- 数组线性表ArrayList的内部实现
- 模仿ArrayList类的内部实现
- ArrayList内部实现
- 浅析 KVO 内部实现
- Java ArrayList 内部源码实现
- Java中ArrayList内部实现
- ArrayList的源码浅析
- java中的线性表的内部实现(ArrayList、LinkedList)
- Java的ArrayList源码浅析
- ArrayList类的代理,其内部实现和ArrayList中完全相同的功能并计算每个方法运行时间。
- jvm的内部体系结构浅析
- jvm的内部体系结构浅析
- jvm的内部体系结构浅析
- jvm的内部体系结构浅析
- jvm的内部体系结构浅析
- jvm的内部体系结构浅析
- jvm的内部体系结构浅析
- 线程
- HDU 1253 胜利大逃亡
- java 多线程并行计算之求素数(星星笔记)
- HDU 4998 Rotate
- 设计模式观后(c++还原之十 代理模式)
- 浅析ArrayList的内部实现
- 关于构造函数
- Longest Consecutive Sequence
- Android关闭软键盘
- hdu5015 矩阵快速幂233(好题)
- 数组最长递增子序列
- 面试题笔记1
- POJ 2348 Euclid's Game(博弈)
- 题目1519:合并两个排序的链表