创建动态数组与系统List对比

创建动态数组:

1.自定义接口,即想实现的方法。

public interface MyList {

	//添加元素
	public void add(int data);
	
	//删除元素
	public int remove(int index);
	
	//获取元素
	public int get(int index);
	
	//获取数组长度
	public int size();
	
	//清空数组
	public void clear();
	
	//判断是否为空数组
	public boolean isEmpty();
	
	//元素排序
	public void sort();
	
	//设置子数组
	public void subList(int fromIndex, int toIndex);
	
	//在指定位置设置数组中的元素
	public void set(int index, int data);
	
	//求元素的索引
	public int indexOf(int data);
	
	//判断元素是否存在
	public boolean contains(int data);
	
	//在指定位置添加指定元素
	public void add(int index, int data);

}

 

2.创建类引用接口,并重写接口中的方法

public class MyListArray implements MyList{
	
	private int size=0;
	private int[] array = new int[size];
	
	//添加元素
	public void add(int data) {
		int[] newarr = new int[array.length+1]; //新数组的长度要比原来的数组多1
		for(int i=0; i<array.length;i++) {
			newarr[i] = array[i];
		}
		newarr[array.length] = data; //更新原来数组
		array = newarr;
		size++;
	}
			
	//删除元素
	public int remove(int index) {
		int[] newarr = new int[array.length-1];  //新数组的长度比原来数组少1
		int a=0,j=0;
		size = array.length;
		for(int i=0;i<array.length;i++) {
			if(i!=index) {
				newarr[j] = array[i];   //删除 数组中的元素是,新数组的下标变量应与原数组不同
				j++;
			}
			else {
				a = array[index];
			}
		}
		size--;
		array = newarr;  //更新原来数组
		return a;
		
	}
			
	//获取元素
	public int get(int index) {
		int a = 0;
		if(index<array.length) {
			a = array[index];
		}
		else {
			System.out.println("index is out of the bound");
		}
		return a;
	}
			
	//获取数组长度
	public int size() {
		int MAX_VALUE = 2147483647;
		if(size < MAX_VALUE) {
			return size;
		}
		else {
			return MAX_VALUE;
		}
	}
	
	//清空数组
	public void clear() {
        array = new int[0];
        size = 0;
	}
	
	//判断是否为空数组
	public boolean isEmpty() {
		if(array.length == 0) {
			return true;
		}
		else {
			return false;
		}
	}
	
	//元素排序
	public void sort() {
		for(int i=0;i<array.length-1;i++) {
			for(int j=0;j<array.length-i-1;j++) {
				if(array[j]>array[j+1]) {
					int temp = array[j];
					array[j] = array[j+1];
					array[j+1] = temp;
				}
			}
		}
	}
	
	//设置子数组,不包含第二个参数所对应的元素
	public void subList(int fromIndex, int toIndex) {
		int[] arr = new int[toIndex-fromIndex];
		if(toIndex == fromIndex) {
			System.out.println("The list is empty.");
		}
		int j = 0;
		for(int i=fromIndex;i<toIndex;i++) {
			arr[j] = array[i];
			j++;
		}
		array = arr;
		size = toIndex-fromIndex;  //更新size
	}		
	
	//设置数组中的元素
	public void set(int index, int data) {
		array[index] =data;
	}

	//求元素的索引
	public int indexOf(int data) {
		for(int i=0;i<array.length;i++) {
			if(array[i] == data) {
				return i;
			}
		}
		return -1;
	}
	   
	
	//判断元素是否存在
	public boolean contains(int data) {
		for(int i=0;i<array.length;i++) {
			if(array[i] == data) {
				return true;
			}
		}
		return false;
	}
	
	//在指定位置添加指定元素
	public void add(int index, int data) {
		int[] arr = new int[array.length+1];
		for(int i=0;i<array.length+1;i++) {
			if(i < index) {
				arr[i] = array[i];
				
			}
			else if(i == index) {
				arr[i] = data;
			}
			else {
				arr[i] = array[i-1];
			}
		}
		array = arr;
		size = array.length;
	}

}

 

3.主程序使用自定义动态数组,执行相同的命令,对比系统类List所消耗的时间。

import java.util.List;
import java.util.ArrayList;

public class Main {

	public static void main(String[] args) {

		MyListArray mla = new MyListArray();
		
		long start = System.currentTimeMillis();
		
		
		for(int i=0; i<10000; i++) {
			mla.add(i);
		}
		System.out.println("这个数组的长度是"+mla.size());
		System.out.println("第15个元素为"+mla.get(14));
		System.out.println("删除的第6个元素为"+mla.remove(5));
		System.out.println("这个数组的长度是"+mla.size());
		mla.clear();
		System.out.println("这个数组的长度是"+mla.size());
		System.out.println("数组是空数组吗? "+mla.isEmpty());
		
		//排序用时和list相同
		mla.add(2);
		mla.add(8);
		mla.add(1);
		mla.add(5);
		mla.add(3);
		mla.sort();
		mla.subList(0, 4);
		for(int k=0;k<mla.size();k++) {
			System.out.print(mla.get(k)+" ");
		}
		System.out.print("\n");
		System.out.println("这个数组的长度是"+mla.size());
		mla.set(3, -600);
		for(int k=0;k<mla.size();k++) {
			System.out.print(mla.get(k)+" ");
		}
		System.out.print("\n");
		System.out.println("这个元素的索引是"+mla.indexOf(2));
		System.out.println("这个元素是否存在?"+mla.contains(5));
		mla.add(2, -15);
		for(int k=0;k<mla.size();k++) {
			System.out.print(mla.get(k)+" ");
		}
		
		
		
		long end = System.currentTimeMillis();
		System.out.println("\n"+"消耗时间为"+(end-start)+"ms"+"\n");
		
		//对比系统设计好的List 
		List<Integer> list = new ArrayList<Integer>();
		
		long start2 = System.currentTimeMillis();
		
		
		for(int i=0; i<10000; i++) {
			list.add(i);
		}
		System.out.println("这个数组的长度是"+list.size());
		System.out.println("第15个元素为"+list.get(14));
		System.out.println("删除的第6个元素为"+list.remove(5));
		list.clear();
		System.out.println("这个数组的长度是"+list.size());
		System.out.println("数组是空数组吗? "+list.isEmpty());
		
		list.add(2);
		list.add(8);
		list.add(1);
		list.add(5);
		list.add(3);
		list.sort(null);
		list = list.subList(0, 4);
		System.out.println(list);
		System.out.println("这个数组的长度是"+list.size());
		list.set(3, -600);
		System.out.println(list);
		System.out.println("这个元素的索引是"+list.indexOf(2));
		System.out.println("这个元素是否存在?"+list.contains(5));
		list.add(2, -15);
		System.out.println(list);
		
		long end2 = System.currentTimeMillis();
		System.out.println("消耗时间为"+(end2-start2)+"ms");
		
	}

}

 

经过对比,使用自定义动态数组所使用的消耗时间是使用List的几十倍。

原因(个人理解):(1)自定义的动态数组初始化长度为0,而List的初始化DFAULT_CAPEACITY = 10;(2)自定义动态数组添加元素时,每增加一次元素新建一次数组原数组长度多1的数组。在List中,如果添加元素的个数超过了原来的capacity,则新数组扩容到原数组的1.5倍 newCapacity = oldCapacity + (oldCapacity >>1)。如果再不够用,再扩容1.5倍。而不是每次添加元素,长度都增加1。

上述自定义动态数组有个缺点,只能往里输入整数类型。如何定义字符串数组,或者组件数组呢?这个时候,我们用到了Object类以及泛型< >。

1)定义接口时,用到泛型<E>。

public interface MyList<E> {

	//添加元素
	public void add(E data);
	
	//删除元素,注意这里返回的不是某个确定的数据类型
	public E remove(int index);
	
	//获取元素
	public E get(int index);
	
	//获取数组长度
	public int size();
	
	//清空数组
	public void clear();
	
	//判断是否为空数组
	public boolean isEmpty();
	
	//设置子数组
	public void subList(int fromIndex, int toIndex);
		
	//在指定位置设置数组中的元素
	public void set(int index, E e);
	
	//求元素的索引
	public int indexOf(E e);
	
	//判断元素是否存在
	public boolean contains(E e);
	
	//在指定位置添加指定元素
	public void add(int index, E e);	

}

 

2)重写接口里面的方法时,注意泛型数据类型。在此定义数组时,用到Object[ ] obj = new Object[ length ]。要注意强制转换成E类型(E)obj

public class MyListArray<E> implements MyList<E>{
	
	private int size=0;
	private Object[] array = new Object[0];  //这里的定义为Object
	
	//添加元素
	public void add(E data) {
		Object[] newarr = new Object[array.length+1]; //新数组的长度要比原来的数组多1
		//复制原数组里的数据
		for(int i=0; i<array.length;i++) {
			newarr[i] = array[i];
		}
		newarr[array.length] = data; //更新原来数组
		array = newarr;
		size++;
	}
			
	//删除元素
	public E remove(int index) {
		Object[] newarr = new Object[array.length-1];  //新数组的长度比原来数组少1
		int j=0;
		E a = null;
		size = array.length;
		for(int i=0;i<array.length;i++) {
			if(i!=index) {
				newarr[j] = array[i];   //删除 数组中的元素是,新数组的下标变量应与原数组不同
				j++;
			}
			else {
				a = (E) array[index];  //强制转换,将Object转换到E
			}
		}
		size--;
		array = newarr;  //更新原来数组
		return a;
		
	}
			
	//获取元素
	public E get(int index) {
		E a =null;
		if(index<array.length) {
			a = (E) array[index];
		}
		else {
			System.out.println("index is out of the bound");
		}
		return a;
	}
			
	//获取数组长度
	public int size() {
		return size;
	}
	
	//清空数组
	public void clear() {
        array = new Object[0];
        size = 0;
	}
	
	//判断是否为空数组
	public boolean isEmpty() {
		if(array.length == 0) {
			return true;
		}
		else {
			return false;
		}
	}
	
	//设置子数组,不包含第二个参数所对应的元素
	public void subList(int fromIndex, int toIndex) {
		Object[] arr = new Object[toIndex-fromIndex];
		if(toIndex == fromIndex) {
			System.out.println("The list is empty.");
		}
		int j = 0;
		for(int i=fromIndex;i<toIndex;i++) {
			arr[j] = array[i];
			j++;
		}
		array = arr;
		size = toIndex-fromIndex;  //更新size
	}			

	//设置数组中的元素
	public void set(int index, E e) {
		array[index] = e;
	}
	
	//求元素的索引
	public int indexOf(E e) {
		for(int i=0;i<array.length;i++) {
			if(array[i] == e) {
				return i;
			}
		}
		return -1;
	}
	   
	
	//判断元素是否存在
	public boolean contains(E e) {
		for(int i=0;i<array.length;i++) {
			if(array[i] == e) {
				return true;
			}
		}
		return false;
	}
	
	//在指定位置添加指定元素
	public void add(int index, E e) {
		Object[] arr = new Object[array.length+1];
		for(int i=0;i<array.length+1;i++) {
			if(i < index) {
				arr[i] = array[i];
				
			}
			else if(i == index) {
				arr[i] = e;
			}
			else {
				arr[i] = array[i-1];
			}
		}
		array = arr;
		size = array.length;
	}
		
}

 

3)主程序调用时,要声明<E>的数据类型,比如String,Integer...。注意,只能是引用类型(类 ,数组,接口)

	public static void main(String[] args) {

		//E只能使用引用类型
		MyListArray<String> mla = new MyListArray<String>();
		
		
		for(int i=0; i<10000; i++) {
			mla.add("er");
		}
		System.out.println("这个数组的长度是"+mla.size());
		System.out.println("第15个元素为"+mla.get(14));
		System.out.println("删除的第6个元素为"+mla.remove(5));
		mla.clear();
		System.out.println("这个数组的长度是"+mla.size());
		System.out.println("数组是空数组吗? "+mla.isEmpty());
		
		//排序用时和list相同
		mla.add("he");
		mla.add("she");
		mla.add("they");
		mla.add("me");
		mla.subList(0, 3);
		for(int k=0;k<mla.size();k++) {
			System.out.print(mla.get(k)+" ");
		}
		System.out.println();
		mla.set(1,"we");
		for(int k=0;k<mla.size();k++) {
			System.out.print(mla.get(k)+" ");
		}
		System.out.println();
		System.out.println("这个元素的索引是"+mla.indexOf("she"));
		System.out.println("这个元素是否存在?"+mla.contains("they"));
		mla.add(2, "it");
		for(int k=0;k<mla.size();k++) {
			System.out.print(mla.get(k)+" ");
		}	
		
	}

 

以上内容仅作为初学者的浅薄理解。有一篇相关文章写的蛮好https://blog.csdn.net/baidu_40188909/article/details/108412788?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162126647516780265455568%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162126647516780265455568&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-1-108412788.first_rank_v2_pc_rank_v29&utm_term=%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8A%A8%E6%80%81%E6%95%B0%E7%BB%84%E4%B8%8EList%E5%8C%BA%E5%88%AB&spm=1018.2226.3001.4187

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值