自己封装ArrayList类

ArrayList底层实现
原博客地址
ArrayList源代码解析
参考文章(ArrayBox))

package testList;
import java.io.Serializable;
import java.util.RandomAccess;
/**
 * 自己动手编写ArrayList代码
 * 实现的ArrayList主要的功能如下:默认构造器和一个参数的有参构造器
 * add方法;get方法;indexOf方法;contains方法;size方法;isEmpty方法;remove方法
 * @author mmz
 */
public class SimpleArrayList<E> implements RandomAccess,Cloneable,Serializable{
	private static final int DEFAULT_CAPICITY=10;//常量一般都是static final修饰
	int size=0;//用来记录数组内存储的有效元素个数,而不是数组空间
	private Object[] elementData;//声明一个数组变量elementData
	//java源码:private transient Object[] elementData; transient让某些被修饰的成员属性变量不被序列化
	//ArrayList无参构造器
	public SimpleArrayList() {
		this(DEFAULT_CAPICITY);//构造函数重载,this()调用的其实就是构造函数,此处调用的是有参构造函数
	}
	//ArrayList有参构造器
	public SimpleArrayList(int size) {
		if(size<0) {
			throw new IllegalArgumentException("默认大小"+size);
		}else {
			elementData=new Object[size];//创建大小为size的数组 并将它复制给之前声明为Object[]的变量elementData
		}
	}
	
	//实现add方法(1)
	public void add(E e) {
		isCapicityEnough(size+1);//做一个判断,是否需要扩容。size+1是添加一个元素后数据的总长度
		elementData[size++]=e;	
	}
	
	//实现add方法
	public void add(int index,E e) {//1.java中大部分,可以说全都是从0开始的,比如数组,集合等2.在数据库中则有不少都是从1开始的,首先记录集里是从1开始的,截取字符串时也是从1开始,而java中则是从0开始,
		checkRangeForAdd(index);
		isCapicityEnough(size+1);
		System.arraycopy(elementData,index,elementData,index + 1,size - index);
		elementData[index] = e;
		size++;
/**
 * System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制。
 * 其函数原型是:public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
 * src:源数组; 
   srcPos:源数组要复制的起始位置;
   dest:目的数组; 
   destPos:目的数组复制的起始位置; 
   length:复制的长度。
        注意:src and dest都必须是同类型或者可以进行转换类型的数组 
   int[] ids = { 1, 2, 3, 4, 5 };
   System.out.println(Arrays.toString(ids)); // [1, 2, 3, 4, 5]
   // 把从索引0开始的2个数字复制到索引为3的位置上
   System.arraycopy(ids, 0, ids, 3, 2);//[1, 2, 3, 1, 2]
 */
	}
	//判断是否需要扩容,不需要的话算了,需要就用explicitCapacity扩
	public void isCapicityEnough(int size) {
		if(size>DEFAULT_CAPICITY) {//如果数据的长度大于默认空间,则扩容
			explicitCapacity(size);
		}
		if(size<0) {
			throw new OutOfMemoryError();
		}
	}
	//扩容函数
	private final static int MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;//??
	public void explicitCapacity(int capacity) {
		int newLength=elementData.length*2;//按照两倍扩容
		if(newLength-capacity<0) {//如果扩容后长度仍然小于加入新元素后数组的长度,则将加入新元素后数组的长度赋值给新长度
			newLength=capacity;
		}
		if(newLength>MAX_ARRAY_LENGTH) {//判断若扩容后长度大于给定的最大值,则新长度重新赋值
			newLength=((capacity>MAX_ARRAY_LENGTH)?Integer.MAX_VALUE:MAX_ARRAY_LENGTH);
		}
	}
	//判断是否越界
	public void checkRangeForAdd(int index) {//java中的索引一般是从0开始;数据库中index一般从1开始
		if(index<0||index>size) {
			throw new IndexOutOfBoundsException("指定的index超过界限");
		}
		
	}
	//实现get方法,get方法用来得到容器中指定下标的元素。方法实现比较简单,直接返回数组中指定下标的元素即可。
	public E getElement(int index) {
		checkRangeForAdd(index);
		return (E) elementData[index];
	}
	//实现indexOf方法用来得到指定元素的下标。实现起来比较简单,需要判断传入的元素,
	public int indexOf(	Object o) {
		if(o!=null) {//判断传入的元素是否为null
			for(int i=0;i<size;i++) {
				if(elementData[i].equals(o)) {
					return i;
				}
			}
		}else {
			for(int i=0;i<size;i++) {
				if(elementData[i]==null) {
					return i;
				}
			}
		}
		return -1;//匹配成功就返回下标,匹配失败就返回-1。因为返回值类型是int	
	}
	//contains方法,用来判断该容器中是否包含指定的元素。
	public boolean contains(Object o) {
		return indexOf(o)>=0;//根据指定元素,寻找索引值,根据indexOf方法,若找不到该元素就返回-1,所以若indexOf返回大于0则
	}
	
	//size方法用来得到容器类的元素个数
	public int size() {
		return size;//elementData.length
	}
	//isEmpty方法用来判断容器是否为空
	public boolean isEmpty() {
		return size()==0;
	}
	//remove方法(1)是用来对容器类的元素进行删除
//	public void remove(Object o) {
//		int aindex=indexOf(o);
//		System.arraycopy(elementData, aindex+1, elementData, aindex, size-aindex);
//		elementData[size-1]=null;
//	}自己写的,不知道ok否
	
	public E remove(int index) {
		E value = getElement(index);
        int moveSize = size - index - 1;
        if (moveSize > 0){
            System.arraycopy(elementData,index + 1, elementData,index,size - index - 1);
        }
        elementData[--size] = null;
        return value;//返回被删除的元素
	}
	
	public boolean remove(Object o) {
		if(contains(o)) {
			remove(indexOf(o));
			return true;
		}else {
			return false;
		}
	}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值