您的位置:首页 > 其它

自定义ArrayList类,实现自动扩容

2018-07-14 17:15 197 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_41536539/article/details/81045466

                                                        对ArrayList扩容机制的理解首先我们要知道ArrayList本质上是一维数组,再从它的功能出发谈谈它的扩容机制.第一:我们知道ArrayList集合里面能放所有类型的数据,这就必须要求我们把ArrayList定义成泛型类ArrayList<E>,同时在这个类里面真正存放数据的地方是一个数组,在这里我把这个数组名叫做data;开头我们讲过, ArrayList集合里面能放所有类型的数据,也就是这个data 数组能存放所有类型的数据,所以我们必须把这个数组的类型定义成Object类,开始的时候, ArrayList集合还没有添加数据之前,这个数组是空的,这里我们定义一个int型变量size来描述往集合中添加元素的个数,没有添加数据之前,size=0.第二:我们要了解一个类,首先要了解它的构造方法是怎样的,对于ArrayList这个类也是如此,它的有参构造方法的参数是(int capacity),方法体是:data=new Object[capacity],这个构造方法的作用是定义data数组,规定这个数组的长度为capacity,注意:不要把数组的长度capacity和size搞混;接着我们再来看看它的无参构造方法,方法体是:this(10),该方法的作用是:调用有参构造方法,此时:data=new Object[10],这里相当于初始化了这个数组,定义数组的长度为10,没有添加元素之前,这个数组里面是10个0或10个null(相当于分配一个容量为10的空间).第三:往数组中添加数据.在添加第一个元素的时候,我们定义一个方法add(E element),这个数组的类型是Object,所以这个数组中元素的类型也是泛型的,进入方法体,我们首先获得数组的长度,我们定义一个int len=data.length;接着我们把这个len与size的大小进行比较,如果不相等,说明这个数组还有容量,可以继续添加元素,没必要给这个数组扩容;如果相等,说明这个数组中添加的元素已经满了,不能再加了,此时就要给这个ArrayList集合一个扩容的机制,我们定义一个新的变量int newCapacity=len+(len>>1),这个newCapacity始终是len的1.5倍,同时利用Arrays工具类的copyOf(data,newCapacity)方法,把data数组中元素拷贝到一个容量(长度)为newCapacity的新数组中去,栈区中的对象引用data会指向新数组的内存地址;在这里需要额外说明的是,原数组中的元素不会改变,但是由于原数组失去了对象引用,最终堆内存会被GC回收(GC的启动是不定时的).最后,我们需要定义添加进去的元素位于数组中什么位置:data[size++]=element.下面是我写的代码,写的不好,请多指教:package com.lyt.beans;


import java.util.Arrays;


/*
 * 自定义ArrayList集合,
 * 方法有:1.往集合中添加元素,并且在第一次添加元素的时候实现自动扩容;
 * 2.查看集合大小(查看集合中元素的个数);3.通过下标访问元素
 */
public class ArrayList<E> {
private Object[] data=null;
private int size;
//编写有参的构造方法
public ArrayList(int capacity){
data=new Object[capacity];
}
//定义无参的构造方法
public ArrayList(){
//调用有参的构造方法
this(10);
}
//方法-:往集合中添加元素,并实现自动扩容
public void add(E element){
int length=data.length;
//添加元素之前,把数组的容量与数组中元素的个数进行比较
if(size==length){
//扩容后的容量
int newCapacity=length+(length>>1);
//数组拷贝
data=Arrays.copyOf(data,newCapacity);
}
data[size++]=element;
}
//方法二:查看数组中元素的个数(数组的大小)
public int size(){
return size;
}
//方法三:通过下标获取元素
@SuppressWarnings("unchecked")
public E get(int index){
if(index>=size){
//抛出下标越界异常
throw new  ArrayIndexOutOfBoundsException("index:"+index+"size:"+size);
}
return (E) data[index];
}


}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: