【JAVA】ArrayList手動實現(初級)

_chacha發表於2019-01-24

在實現畫圖板時需要使用ArrayList,要求自己實現,只實現了畫圖板現階段需要的功能與一些基礎功能,很粗糙,還沒有考慮優化。

20190124第一次更新

 

在動手實現之前,首先考慮我們需要什麼功能?

計算機顯示影像只顯示最頂層的(即我們眼睛所能看到的部分),底層的影像拖到頂層時會從視訊記憶體裡讀取影像的資料重新載入,這就要求我們儲存相應的資料。畫圖板同理,它需要存放所畫的圖形資料,以便在需要的時候將其載入到螢幕上,所以我們的畫圖板需要一個可以存放圖形資料的陣列,可以往裡面新增圖形,也可以刪除圖形。在畫圖時並不確定會畫多少圖形,因此陣列大小是可以自動變化的。

知道了需求,下面就根據需求手動實現ArrayList,我們可以稱之為MyArrayList

存入陣列的物件不確定,可能是直線,也可能是圓,因此需要用到泛型,如下所示

public class MyArrayList<E>{
 ……
}

要求陣列大小可以根據畫的圖形數量自動變化,那麼我們需要統計往陣列裡實際放了多少個資料(count)、陣列的初始容量(initCapatity)、陣列容量的增量(increment),此外還需一個可以存放任意物件的陣列Object[] src

 public class MyArrayList<E> {
     int count = 0;
     // 陣列初始大小為10 
     int initCapatity = 10;
     // 增量 
     int increment; 
     Object[] src;
}

通過new一個物件的方式獲取陣列,有兩種方式,一個是用無參的構造方法,一個有參的構造方法,引數為初始陣列大小,增量都為初始大小的一半

public MyArrayList () {
     increment = (int)(initCapacity * 0.5);
     src = new Object[initCapacity];
 }
public MyArrayList(int initCapacity) { this.initCapacity = initCapacity; increment = (int)(initCapacity * 0.5); src = new
Object[initCapacity]; }

每畫一個圖形就要新增一個資料,因此要有add方法

/**

* 在陣列末尾增加一個資料

* 

* @param data 要增加的資料

*/

public void add(E data) {
    // 如果傳入資料的數量大於陣列容量,則新建陣列,增量為increment
    if (count >= src.length) {
        Object[] dest = new Object[src.length + increment];
        // 使用native方法,提高效率
        System.arraycopy(src, 0, dest, 0, src.length);
           src = dest;
    }
    src[count++] = data;
}        

另外有一些ArrayList需要實現的基本方法

/**
* 在指定下標位置新增一個資料 * * @param index 要新增資料的位置 * @param data 要新增的資料 */
public void add(int index, E data) { Object[] dest; if (count >= src.length) { dest = new Object[src.length + increment]; System.arraycopy(src, 0, dest, 0, index); System.arraycopy(src, index, dest, index + 1, src.length - index); } else { dest = src; System.arraycopy(src, 0, dest, 0, index); System.arraycopy(src, index, dest, index + 1, count - index); } src = dest; src[index] = data; count++;
}
/** * 刪除指定的資料,如果有多個相同的資料,則刪除第一個
* *
@param data 要刪除的資料 */ public void delete(E data) { Object[] dest = src; int i; for (i = 0; i < count; i++) { if (src[i] == data) { break; } } System.arraycopy(src, 0, dest, 0, i); System.arraycopy(src, i + 1, dest, i, count - 1 - i); dest[count - 1] = null; src = dest; count--; } /** * 刪除指定的資料,根據引數isAll來確定是否刪除所有與指定資料相同的資料 * * @param data 要刪除的資料 * @param isAll 是否刪除刪除所有與指定資料相同的資料 */ public void delete(E data, boolean isAll) { if (isAll == false) { this.delete(data); } else { Object[] dest = src; int tempCount = 0;// 臨時計數器,記錄要刪除的元素的個數 for (int i = 0, j = 0; i < count; i++, j++) { if (src[i] == data) { dest[j] = src[i + 1]; i++; tempCount++; } else { dest[j] = src[i]; } } for (int i = count - tempCount; i < count; i++) { dest[i] = null; } src = dest; count -= tempCount; } } /** * 刪除指定下標位置的元素 * * @param index 要刪除元素的下標 */ public void delete(int index) { Object[] dest = src; System.arraycopy(src, 0, dest, 0, index); System.arraycopy(src, index + 1, dest, index, count - index - 1); dest[count - 1] = null; src = dest; count--; } /** * 根據下標更新元素 * @param index 要更新的元素下標 * @param data 新元素 */ public void update(int index, E data) { src[index] = data; } /** * 根據下標獲取對應位置的元素 * * @param index 要取出的元素下標 */ public E get(int index) { return (E) src[index]; } /** * 獲取陣列的元素個數 * * @return 返回元素個數 */ public int size() { return count; }

 

 

 

  

  

相關文章