数据结构(一)——封装动态数组

在Java中创建一个数组,Java对这个数组只提供了下面的一些方法;数组一旦声明,其存储的数据类型和数组的容量大小就一定;且不提供对数组的增删改查操作,需要自己实现;


下面是对静态数组的改进,实现存储任意类型、提供增删改查操作、可扩容:

package com.itheima.array;

/**
 * @author GuoBaoYu
 *	使用泛型,可以存放任意类型的数据;
 */
public class Array<E> {
	private E[] data;   //内部是静态数组
	private int size;
	
	public Array(int capacity) {
		data =(E[]) new Object[capacity];
		size = 0;
	}
	
	/**
	 * 默认构造一个容量为10的数组
	 */
	public Array() {
		this(10);
	}
	
	public int getCapacity(){
		return data.length;
	}
	
	public boolean isEmpty(){
		return size==0 ;
	}
	
	public int getSize(){
		return size;
	}
	
	public void addLast(E element){
		add(size, element);
	}
	
	public void addFirst(E element){
		add(0,element);
	}
	
	//动态数组进行自动扩容和减少容量
	private void resize(int newCapacity){
		E[] newData = (E[]) new Object[newCapacity];
		for(int i = 0; i < size;i++){
			newData[i] = data[i];
		}
		data = newData;
	}
	
	/**
	 * @param index
	 * @param element
	 * 向指定的位置插入元素
	 */
	public void add(int index,E element){
		if(size == getCapacity()){
//			throw new IllegalArgumentException("AddLast is failed. Array is full.");
//		之前如果数组空间满了,抛出异常;现在进行扩容
			int newCapacity = getCapacity()*2;
			resize(newCapacity);
		}
		
		if(index < 0 || index > size){
			throw new IllegalArgumentException("Argument index is illegal.index is required index >=0 and index <= size. ");
		}
		
		for(int i = size-1; i>=index; i--){
			data[i+1] = data[i];
		}
		data[index] = element;
		size++;
	}

	@Override
	public String toString(){
		StringBuilder builder = new StringBuilder();
		builder.append(String.format("size = %d,capacity = %d\t", size,getCapacity()));
		builder.append("[");
		for(int i = 0; i < size; i++){
			builder.append(data[i]);
			if(i<size-1){
				builder.append(",");
			}
		}
		builder.append("]");
		return builder.toString();
	}
	
	public E get(int index){
		if(index >=size || index <0){
			throw new IllegalArgumentException("Argument index is illegal.");
		}
		return data[index];
	}
	
	public void set(int index, E element){
		if(index >=size || index <0){
			throw new IllegalArgumentException("Argument index is illegal.");
		}
		data[index] = element;
	}
	
	public boolean contains(E element){
		for(int i =0; i <size;i++){
			if(data[i].equals(element)){
				return true;
			}
		}
		return false;
	}
	
	public int find(E element){
		for(int i=0 ; i < size; i++){
			if(data[i].equals(element)){
				return i;
			}
		}
		return -1;
	}
	
	//删除index位置的元素,并返回删除的元素的值
	public E remove(int index){
		if(index < 0 || index >= size){
			throw new IllegalArgumentException("Remove failed.index is an illegal argument.");
		}  
		E element = data[index];
		for(int i = index+1; i < size; i++){
			data[i-1] = data[i];
		}
		size--;
		
		//改善算法性能;进行懒缩容;
		if(size <= getCapacity() /4 && data.length/2 !=0){
			resize(getCapacity()/2);
		}
		return element;
	}
	
	//删除第一个元素
	public E  removeFirst(){
		return remove(0);
	}
	//删除最后一个元素
	public E removeLast(){
		return remove(size-1);
	}
	
	/**
	 * @param element
	 * @return
	 * 删除指定的数据
	 */
	public boolean removeElement(E element){
		int find = find(element);
		if(find!=-1){
			remove(find);
			return true;
		}
		return false;
	}
}

思路:

   1.使用泛型,使得可以存储任意类型的数据

   2.在进行添加操作时,如果数组存储数据的个数size已经等于数组创建时声明的容量capacity,则进行自动扩容:创建一个2倍容量的新临时数组newData,将原来的数组data中的数据复制到newData中,再更改data的指向;相当于对data进行了扩容;


类似的,当数组中的数据很少时,可以自动缩容:


猜你喜欢

转载自blog.csdn.net/baoyu_G/article/details/80930485