Java入門——自己寫ArrayList的增刪查改方法

爲了鍛鍊思路,鞏固之前學的簡單知識,試着自己寫一下ArrayList類。

用數組來實現ArrayList類。ArrayList類和數組很像,但是數組是定長不可改的,ArrayList不定長。

 

目錄

構造MyArrayList類

添加操作add()

刪除操作remove()

查找操作search()

修改操作set()


 

構造MyArrayList類

我用了泛型來構造

package MyArrayList;

/**
 * 自己寫的ArrayList類
 * 
 * @author july
 *
 * @param <T> 泛型
 */
class MyArrayList<T> {

	private T[] array; // 本質是對數組的操作
	private int index=0; // 記錄當前最後一個元素的下標

	/**
	 * 無參構造方法
	 */
	MyArrayList() {
		array = (T[]) new Object[10]; // 創建泛型數組,初始長度設爲10
	}

	/**
	 * 有參構造方法
	 * 
	 * @param size 存儲長度
	 */
	MyArrayList(int size) {
		array = (T[]) new Object[size];
	}


}

爲了方便之後的操作,這裏寫兩個方法。一個是用於規範其輸出格式的toString()方法,一個是類私有的設置集合當前最後一個元素的下標的方法setIndex()

public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("[");
		for (T obj : array) {// 循環遍歷數組
			if (obj == null)
				break;
			sb.append(obj);
			sb.append(",");
		}
		// 去除最後一個逗號
		sb.deleteCharAt(sb.length() - 1);
		sb.append("]");
		return sb.toString();

	}
/**
	 * 設置數組的最後一個元素的下標值
	 */
	private void setIndex() {
		for (int i = 0; i < array.length; i++) {
			if (array[i] == null) {
				index = i - 1; // 記錄下最後一個元素的下標
				break;
			}else {
				index=i;//全滿時候
			}
		}
	}

添加操作add()

我重載了兩個添加操作方法,一個是直接添加到末尾,一個是插入操作,插入到某個下標位置。書寫時候需要考慮用於實現的數組是否已經滿了,如果滿了,則需要創建新的更大的數組進行操作。

添加操作:

/**
	 * 增加元素操作,增加到末尾
	 * 
	 * @param object
	 * @return
	 */
	void add(T object) {
		//獲取當前數組最後一個下標
		setIndex();
		if (index == array.length-1) { // 數組滿了,需要創建新數組
			T[] temp = (T[]) new Object[array.length * 2]; // 創建新數組
			System.arraycopy(array, 0, temp, 0, array.length); // 複製數組
			// 將array指向新創建的數組
			array = temp;
			// 重新給index賦值爲當前可以插入元素的下標
			setIndex();
		}

		// 插入元素到數組末尾位置
		array[index+1] = object;
	}

插入操作:

/**
	 * 插入操作
	 * @param desIndex 插入位置
	 * @param obj 插入元素
	 */
	void add(int desIndex,T obj) {
		//先判斷下標是否越界
		setIndex();
		if(desIndex>index+1) {//最後一個位置也可以插入
			try {
				throw new Exception("下標越界");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else if(desIndex == index+1) {
			//插入到末尾
			add(obj);
		}else {
			//在前面的其他位置插入元素
			for(int i=index;i>=desIndex;i--) {
				//先把元素向後移動一位,空出需要插入的位置
				array[i+1]=array[i];
			}
			//可以插入元素了
			array[desIndex]=obj;
		}
	}

測試類:

package MyArrayList;


//測試自己寫的ArrayList類
public class TestMyArrayList {
	
	public static void main(String[] args) {
		//創建整型ArrayList
		MyArrayList<Integer> myInt=new MyArrayList<Integer>();
		myInt.add(0);
		myInt.add(1);
		myInt.add(2);
		myInt.add(3);
		myInt.add(4);
		myInt.add(5);
		System.out.println(myInt.toString());
		
		//創建字符型的ArrayList
		MyArrayList<String> myChar=new MyArrayList<String>();
		myChar.add("a");
		myChar.add("b");
		myChar.add("c");
		myChar.add("d");
		myChar.add("e");
		myChar.add("f");
		myChar.add("g");
		System.out.println(myChar.toString());
		
		
	}
	
	

}

插入操作的效果:

myInt.add(0, -1);


myChar.add(0, "start");

 

刪除操作remove()

刪除操作我重載了兩種,一種是刪除某個下標的值,另一個是根據值查找然後刪除。刪除某位置的元素後要把後面的部分往前移動佔掉空的位置

根據下標刪除:(需要注意下標是否越界)

/**
	 * 刪除操作
	 * 
	 * @param desIndex 需要刪除的元素下標
	 */
	void remove(int desIndex) {
		if (array[desIndex] == null) {
			// 該下標位置沒有值
			try {
				throw new Exception("該位置沒有值,無法進行刪除操作");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			array[desIndex] = null; // 先刪除該處的值
			for (int i = desIndex; i <= index; i++) { // 移動後面的值,填補刪除的地方
				array[i] = array[i + 1];
			}
			// 把最後一個位置置空
			array[index + 1] = null;
		}

	}

根據值查找來刪除:(需要注意該值是否存在)

這裏使用了自己寫的查找函數(寫在下面了)

/**
	 * 刪除操作 注:如果有多個相同的元素,只刪除第一個
	 * 
	 * @param obj 需要刪除的元素
	 */
	void remove(T obj) {
		// 調用查找方法尋找該值的下標
		int i = search(obj);
		if (i != -1) {
			remove(i); // 直接調用前面方法來刪除
		} else {
			// 沒有找到
			try {
				throw new Exception("沒有找到該元素");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

查看效果:

 //根據下標刪除
myInt.remove(4); 
myChar.remove(4);

//根據值查找刪除
myInt.remove((Integer)14); 
myChar.remove("f");

(坑)注意:因爲第一個對象myInt將泛型使用成Integer了,直接寫14會自動調用第一個remove方法(根據下標),將拋出異常下標越界,需要顯式將int轉爲Integer纔可以使用。

 

查找操作search()

根據值查找,返回下標。若沒有找到,返回-1

/**
	 * 查找
	 * 
	 * @param object 需要查找的元素
	 * @return 元素所在下標,若沒有找到,返回-1
	 */
	int search(T object) {
		for (int i = 0; i < array.length; i++) {
			if (array[i] == object) {
				return i;
			}
		}
		return -1;

	}

效果查看:

System.out.println(myInt.search(14));
System.out.println(myChar.search("z"));

 

修改操作set()

修改也重載了兩種,一種修改某下標的值,一種是傳入原值,經過查找修改成新的值

/**
	 * 修改操作
	 * @param desIndex 需要修改的下標
	 * @param obj 修改目標元素
	 */
	void set(int desIndex,T obj){
		//首先判斷該下標是否越界
		setIndex();
		if(desIndex>index) {
			try {
				throw new Exception("下標越界");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else {
			array[desIndex]=obj;
		}
	}
	
/**
	 * 修改操作
	 * @param oObj 需要修改的元素值
	 * @param dObj 修改後的元素值
	 */
	void set(T oObj,T dObj) {
		int i=search(oObj);
		if(i==-1) {
			//沒有找到這個元素
			try {
				throw new Exception("沒有找到這個元素");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else {
			array[i]=dObj;
		}
	}

查看效果:

//根據下標修改
myInt.set(4, (Integer)4);
myChar.set(0, "A");

//根據值查找修改
myInt.set((Integer)14, (Integer)4);
myChar.set("z", "A");

(順便試了一下越界的異常)

 

好了,暫時就這些!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章