Java集合 之 动态数组

注意:首先本程序是根据javaeye博主:java_mzd,对里面的代码进行改进,改进的地方如下:

 

1、如何创建动态数组,并且为用户提供了动态扩展数组长度的接口

2、修改在数组指定位置添加元素

3、该数组适应于多线程环境

4、为该类添加删除一个元素的方法

 

 该类的优点:

                  1. 顺序表因为采用顺序存储形式,所以内部使用数组来存储数据
                  2.因为存储的具体对象类型不一定,所以采用泛型操作
                  3.数组操作优点:1.通过指针快速定位到下表,查询快速
 缺点:
                  1、当操作中超过容量时,则需要重新声明数组,并且复制当前所有数据

 

public class ArrayList<E> {
	private Object[] data = null;// 用来保存此队列中内容的数组
	private int current;// 保存当前为第几个元素的指标
	private int capacity;// 表示数组大小的指标
	/***
	 * 扩展数组的长度 ,也就是动态创建数组,默认扩展的长度为10
	 */
	private int extendLength;

	/**
	 * 如果初始化时,未声明大小,则默认为10
	 */
	public ArrayList() {
		this(10);
	}

	/**
	 * 初始化线性表,并且声明保存内容的数组大小
	 * @param initalSize
	 */
	public ArrayList(int initalSize) {
		if (initalSize < 0) {
			throw new RuntimeException("数组大小错误:" + initalSize);
		} else {
			this.data = new Object[initalSize];
			this.current = 0;
			capacity = initalSize;
			extendLength = 10;
		}
	}

	/**
	 * 添加元素的方法 添加前,先确认是否已经满了
	 * @param e
	 * @return
	 */
	synchronized public boolean add(E e) {
		ensureCapacity(current);// 确认容量
		this.data[current] = e;
		current++;
		return true;
	}

	/**
	 * 确认系统当前容量是否满足需要,如果满足,则不执行操作 如果不满足,增加容量
	 * @param cur 当前个数
	 */
	private void ensureCapacity(int cur) {
		if (cur == capacity) {
			// 如果达到容量极限,增加extendLength的容量,复制当前数组
			this.capacity = this.capacity + extendLength;
			Object[] newdata = new Object[capacity];
			System.arraycopy(this.data, 0, newdata, 0, this.capacity
					- extendLength);
			this.data = newdata;
		}
	}

	/**
	 * 得到指定下标的数据
	 * @param index
	 * @return
	 */
	public E get(int index) {
		validateIndex(index);
		return (E) this.data[index];
	}

	/**
	 * 返回当前队列大小
	 * @return
	 */
	public int size() {
		return this.current;
	}

	/**
	 * 更改指定下标元素的数据为e
	 * @param index 
	 * @param e
	 * @return
	 */
	public boolean set(int index, E e) {
		validateIndex(index);
		synchronized(data){
			this.data[index] = e;
		}
		return true;
	}

	/**
	 *  验证当前下标是否合法,如果不合法,抛出运行时异常
	 * @param index 下标
	 */
	private void validateIndex(int index) {
		if (index < 0 || index > current) {
			throw new RuntimeException("数组index错误:" + index);
		}
	}

	/**
	 * 在指定下标位置处插入数据e
	 * @param index 指定数组的位置,从 0 开始
	 * @param e 需要插入的数据
	 * @return 
	 */
	synchronized public boolean insert(int index, E e) {
		validateIndex(index);
		ensureCapacity(current);
		Object[] tem = new Object[current+1];// 用一个临时数组作为备份
		//开始备份数组
//		for (int i = 0; i < current; i++) {
//			if (i < index) {
//				tem[i] = this.data[i];
//			} else if (i == index) {
//				tem[i] = e;
//			} else if (i > index) {
//				tem[i] = this.data[i - 1];
//			}
//		}
		if(index<=0){
			System.arraycopy(data,0,tem,1 , current);
			tem[index]=e;
		}else if(index<=current-1){
			System.arraycopy(data,0,tem,0,index);
			tem[index]=e;
			System.arraycopy(data,index, tem, index+1,current-index);
		}else{
			System.arraycopy(data,0,tem,0,current);
			tem[index]=e;
		}
		current++;
		this.data = tem;
		return true;
	}
	/****
	 * 从数组中删除一个元素
	 * @param e 要删除的元素
	 * @return 如果待删除的元素在数组中没有找到,就返回false,否则返回true
	 */
	public boolean FromArrayDelete(E e) {
		synchronized (data) {
			int n = -1;
			for (int i = 0; i < current; i++) {//在数组中寻找待删除的元素
				if (data[i] == e) {
					n = i;
					break;
				}
			}
			if (n < 0)//如果在数组中没有找到返回false
				return false;
			Object temp[] = new Object[current - 1];
			int j = 0;
			for (int i = 0; i < current; i++) {
				if (i != n)//j++的原因就是,过滤掉删除元素的那个位置
					temp[j++] = data[i];
			}
			current--;
			capacity--;
			data = temp;
			return true;
		}
	}

	public int getExtendLength() {
		return extendLength;
	}

	/***
	 * 可以设置一次性扩展数组的长度
	 * @param extendLength 设置的长度
	 */
	synchronized public void setExtendLength(int extendLength) {
		this.extendLength = extendLength;
	}

	public int getCurrent() {
		return current;
	}

}
 

你可能感兴趣的:(java集合)