创建动态数组:
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)+" ");
}
}