ArrayList动态数组

自定义动态数组模拟ArrayList

  1. 自定义接口
    抽象出这个类所有的功能
 package ArrayListTest;
//封装数组的集合接口,zhi存储字符串
public interface MyList {
	void add(String str);//向集合末尾添加字符串
	void add(int index,String str);//zai指定位置添加字符串
	 String remove(int index);//删除指定位置的字符串
	 void remove(String str);//删除指定内容的字符串  从头查找删一个
	 String get(int index);//获得指定位置的元素
	 String set(int index,String str);//将指定位置的字符串修改为这个字符串,返回删除前的元素
	 int size();//获取当前数组的长度
	 

}
  1. 定义MyArrayList类且实现MyList接口
package ArrayListTest;
//封装一个数组,这个数组比实际的大一点
/*  这个数组用于存储添加的元素
 *   指定一个属性代表存储元素的末尾;这个是真实大小
 * 
 * */
public class MyArrayList implements MyList {
	private int size;//数组中元素的个数
	int arraySize=10;//数组的长度
	String [] array;


	@Override
	public void add(String str) {
		// TODO Auto-generated method stub
		//判断是否需要扩容
		//如果需要扩容,创建一个新的数组,长度为原数组的50%
		//将原数组的内容复制到新数组
		//将参数 str添加到size位置 size++
		if(size==0) {
			array=new String[arraySize];
		}
		if(size>=array.length) {
			String [] newArray=new String[array.length+(array.length>>1)];
			System.arraycopy(array, 0, newArray,0 , array.length);
			
			array=newArray;
		}
		array[size]=str;
		size++;

	}
	@Override
	public void add(int index, String str) {
		// TODO Auto-generated method stub
		if(size>=array.length) {
			String [] newArray=new String[array.length+(array.length>>1)];
			System.arraycopy(array, 0, newArray, 0, array.length);
			array=newArray;
		}
		if(index>=size)
			System.out.println("越界异常");
		for(int i= size-1;i>=index;i--) {
			array[i+1]=array[i];
			
		}
		array[index]=str;

	}

	@Override
	public String remove(int index) {
		// TODO Auto-generated method stub
		//整体前移  size-- size位置给null
		String str=array[index];
		for(int i=index;i<size-1;i++) {
			
		
			array[i]=array[i+1];
			array[size]=null;
			size--;
			
		}	
		return str;
	}

	@Override
	public void remove(String str) {
		// TODO Auto-generated method stub
		for(int i=0;i<size;i++) {
			if(array[i].equals(str)) {
				remove(i);
				break;
			}
		}

	}

	@Override
	public String get(int index) {
		// TODO Auto-generated method stub
		
		return array[index];
	}

	@Override
	public String set(int index, String str) {
		// TODO Auto-generated method stub
		String s=array[index];
		array[index]=str;
		return s;
	}

	@Override
	public int size() {
		// TODO Auto-generated method stub
		return size;
	}



	
}

3.测试类

package ArrayListTest;

public class MyArrayListTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		MyArrayList a=new MyArrayList();
		
		
		a.add("你爹爹");
		int s=a.size();
		System.out.println(s);
		
       
	}

}

空指针异常的出现成因

1.编写抽象类接口

package ArrayListTest2;

public interface MyList {
	void add(String str);//添加元素
	void add(int index,String str);//按下标添加元素
	void remove(String str);//按字符串删除元素
	void remove(int index);//按下标删除元素
	int size();//返回存储元素的实际大小
	void getStr();//遍历当前字符串
}

2.编写自定义MyArrayList类

成员变量中;创建空的数组String array[];
默认值为null
在自定义类MyListArray中;
if(size==0){
String array []=new String[arraySize];
}

 这个中创建的数组array不赋值给成有关变量;会造成之后的空指针异常;看底层源码发现这个array的前身是成员变量中的array。
package ArrayListTest2;

public class MyListArray implements MyList {
	private int size;
	int arraySize=15;
	String array [];//创建了一个为null的空数组;

	@Override
	public void add(String str) {
		// TODO Auto-generated method stub
		if(size==0) {
			String array[]=new String [arraySize];//String array [] =new String[arraySize]  在14行会报空指针异常;需要把这个新建的类赋值给 array
		}
		if(size>=array.length) {//出现过空指针异常   直接点源码发现这个array是成员变量中的array 为空;运行程序会报出空指针异常
			String newArray[]=new String[array.length+10];
			for(int i=0;i<array.length;i++) {
				newArray[i]=array[i];
			}
			array=newArray;
		}
			
			array[size]=str;
			size++;
		
		
	}

	@Override
	public void add(int index, String str) {
		// TODO Auto-generated method stub
		
		if(size==0) {
			String array[]=new String [arraySize];
		}
		if(size>=array.length) {
			String newArray[]=new String[array.length+10];
			for(int i=0;i<array.length;i++) {
				newArray[i]=array[i];
			}}
		for(int i=size-1;i>=index;i--) {
			array[i+1]=array[i];
		}
		array[index]=str;
		size++;
		
	}

	@Override
	public void remove(String str) {
		// TODO Auto-generated method stub
		if(size==0) {
			String array[]=new String [arraySize];
		}
		if(size>=array.length) {
			String newArray[]=new String[array.length+10];
			for(int i=0;i<array.length;i++) {
				newArray[i]=array[i];
			}}
		
		
	}

	@Override
	public void remove(int index) {
		// TODO Auto-generated method stub
		if(size==0) {
			String array[]=new String [arraySize];
		}
		if(size>=array.length) {
			String newArray[]=new String[array.length+10];
			for(int i=0;i<array.length;i++) {
				newArray[i]=array[i];
			}}
		for(int i=index;i<size-1;i++) {
			array[i]=array[i++];
			
		}
		array[size-1]=null;
		size--;
		
	}

	@Override
	public int size() {
		// TODO Auto-generated method stub
		return size;
	}

	@Override
	public void getStr() {
		// TODO Auto-generated method stub
		
	}
	

}

3.测试类

package ArrayListTest2;

public class MyArrayListTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyListArray a=new MyListArray();
		a.add("我是你爸爸");
		a.add("快叫爸爸");
		int s=a.size();
		System.out.println(s);
	}

}
//结果
/*
Exception in thread "main" java.lang.NullPointerException: Cannot read the array length because "this.array" is null
	at ArrayListTest2.MyListArray.add(MyListArray.java:14)
	at ArrayListTest2.MyArrayListTest.main(MyArrayListTest.java:8)

*/

自定义类更改返回值类型;接口的抽象方法也要改返回值类型

1.接口
getsize();的返回值类型错了

在自定义类中;覆写会报错;更改返回值也错;需要更改接口
package ArrayListTest3;

public interface MyList {
	void add(String str);
	void add(int index,String str);
	void remove(int index);
	void remove(String str);
	void getSize();

}

定义类

引用指向未删除的问题

remove中;删除一个元素;需要从前往后整体向前移动一步;
最后一位size-1向前移动一位;删除的位置被后面的覆盖到达删除的目的;但是在最后一位 及size-1的下标位置;向前移动;其本身引用指向的内容并未被覆盖;需要手动 array[size-1]=null垃圾回收掉
1.定义抽象类接口

package ArrayListTest3;

public interface MyList {
	void add(String str);
	void add(int index,String str);
	void remove(int index);
	void remove(String str);
	int getSize();

}

2.自定义ArrayList类
* remove方法中没有回收前移造成的 size-1的位置未被覆盖;引用指向未回收垃圾及未写 array[size-1]=null;

public void remove(int index){
for(int i=index;i<size-1;i++){
array[i]=array[i+1];
}

}

package ArrayListTest3;

public class ArrayList implements MyList {
	private int size;
	int arraySize;
	String array[];
	public ArrayList() {
		arraySize=3;
	}

	public void add(String str) {
		// TODO Auto-generated method stub
		if(size==0) {
			array=new String[arraySize];
		}
		if(size>=array.length) {
			String newArray []=new String[array.length+10];
			for(int i=0;i<array.length;i++) {
				newArray[i]=array[i];
				
			}
			array=newArray;
			
		}
		array[size++]=str;

	}

	@Override
	public void add(int index, String str) {
		// TODO Auto-generated method stub
		if(size==0) {
			array=new String[arraySize];
		}
		if(size>=array.length) {
			String newArray [] =new String[array.length+8];
			for(int i=0;i<array.length;i++) {
				newArray[i]=array[i];
				
			}
			array=newArray;
			
		}
		for(int i=size-1;i>=index;i--) {
			array[i+1]=array[i];
		}
		array[index]=str;
		size++;

	}

	@Override
	public void remove(int index) {
		// TODO Auto-generated method stub
		if(size==0) {
			array=new String [arraySize];
		}
		if(size>=array.length) {
			String newArray []=new String[array.length+10];
			for(int i=0;i<array.length;i++) {
				newArray[i]=array[i];
			}
			array=newArray;
			
		}
		for(int i=index;i<size-1;i++) {
			array[i]=array[i+1];
			
		}
		//array[size-1]=null; 未回收元素最后指向前移 引用未回收的问题
		size--;
		

	}

	@Override
	public void remove(String str) {
		// TODO Auto-generated method stub
		for(int i=0;i<array.length;i++) {
			if(array[i].equals(str)) {
				remove(i);
			}
		}

	}

	@Override
	public int getSize() {
		// TODO Auto-generated method stub
		return size;
		
	}
	public void getArray() {
		for(String s_:array) {
			System.out.println(s_);
		}
	}
	public void getIndex(int index) {
		System.out.println(array[index]);
		
	}

	
}

测试类

package ArrayListTest3;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ArrayList a=new ArrayList();
		a.add("如果我是你爹");
		a.add("给我钱");
		a.add("叫爸爸");
		a.remove(1);
		System.out.println(a.getSize());
		a.getIndex(2);//未回收size-1前移动后;这个位置没有被后者覆盖;引用指向未变
		a.getIndex(1);

	}

}
//结果
/*
2
叫爸爸//本不应存在的一个值
叫爸爸


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值