1. 程式人生 > >Java資料結構-陣列解析及類封裝自定義陣列實現

Java資料結構-陣列解析及類封裝自定義陣列實現

概念:

陣列是Java資料結構中最基本的資料,是儲存 一組長度固定同資料型別的集合。

優點:
  • 插入快:對於無序陣列,只需要在陣列末尾增加資料即可。但對於有序陣列,需要查詢到固定的位置,再插入資料,相對無序陣列
  • 結構簡單
缺點:
  • 根據元素值查詢慢:如果根據下標查詢會比較快,但是根據元素值查詢對於無序陣列需要從第一個元素開始遍歷進行查詢知道查詢到所需要的資料。如果是有序陣列可以通過合適的排序演算法加快查詢速度。
  • 刪除慢:除了需要遍歷查詢到需要刪除的資料外,刪除資料後,後面的資料還需要向前移動一個位置,這也需要耗費較多時間。
  • 長度固定
    :不能動態擴容,如果一開始初始化的長度太大用不著浪費空間,如果一開始初始化的長度太小又裝不下,不夠靈活擴充套件性差。
類封裝實現簡單的陣列結構
/**
 * 自定義類封裝實現陣列,實現基本功能:
 * 增加資料
 * 獲取資料
 * 刪除資料
 * 查詢資料
 * 修改資料
 */

public class MyArrayList {

    private Object[] mArray;  //定義陣列,可以儲存任意資料型別 object

    private int size;//陣列長度

    //無參構造,可以預設 大小
    public MyArrayList() {
        mArray = new Object[10];  //預設初始化 10 大小

    }

    //指定初始化大小
    public MyArrayList(int size) {
        mArray = new Object[size];
    }

    public int getSize() {
        if (mArray == null) {
            throw new NullPointerException("陣列不能為空");
        }
        return size;
    }

    /**
     * 增加資料
     *
     * @param o
     */
    public void add(Object o) {
        mArray[size] = o;    //將資料增加到最後  ,size初始值為0 ,從0開始增加
        size++;

        //是否需要擴容
        if (size >= mArray.length) {
            //增加的資料 大於初始化的陣列長度,裝不下了自動擴容
            int newCapacity = size * 2;    //擴容2倍--類似hashmap 實現原理
            //將原來陣列拷貝到新的陣列
            Object[] newArray = new Object[newCapacity];
            for (int i = 0; i < mArray.length; i++) {
                newArray[i] = mArray[i];
            }

            mArray = newArray;
        }

    }

    /**
     * 在固定的位置增加資料
     *
     * @param index
     * @param o
     */
    public void addWithIndex(int index, Object o) {
        isVaildIndex(index,"陣列越界");
        size++;
        for (int i = index; i < size; i++) {
            mArray[i+1] = mArray[i];
        }
        mArray[index] = o;
    }

    /**
     * 根據下標查詢資料
     *
     * @param index
     * @return
     */
    public Object get(int index) {
        isVaildIndex(index, "陣列越界:不能獲取陣列外的資料");
        return mArray[index];
    }


    /**
     * 根據下標刪除資料,將最後一個數據移動到刪除的資料的位置,然後
     *
     * @param index
     */
    public void delete(int index) {
        isVaildIndex(index, "陣列越界:不能刪除陣列外的資料");

        mArray[index] = mArray[size - 1];
        size--;

        Object[] newArray = new Object[size];
        for (int i = 0; i < size; i++) {
            newArray[i] = mArray[i];
        }

        mArray = newArray;

    }

    /**
     * 根據下標刪除資料,將需要刪除的資料之後的資料往前移
     *
     * @param index
     */
    public void deleteWithIndex(int index) {
        isVaildIndex(index,"陣列越界,不能刪除陣列長度外的資料 2 ");
        if (index < size-1){
            for (int i = 0; i < size-1; i++) {
                mArray[i+index] = mArray[i+index+1];
//                System.out.print("index1 :"+ mArray[i+index]);
            }
        }

        size--;
        //構建新的陣列
        Object[] newArray = new Object[size];
        for (int i = 0; i < size; i++) {
//            System.out.print("index:"+ mArray[i]);
            newArray[i] = mArray[i];
        }
        mArray  = newArray;
    }

    /**
     * 修改元素
     * @param oldObj
     * @param newObj
     */
    public void find(Object oldObj,Object newObj){
        for (int i = 0; i < size; i++) {
            if (mArray[i] == oldObj){
                mArray[i] = newObj;
            }
        }
    }

    /**
     * 刪除某一區間資料
     * @param start
     * @param end
     */
    public void deleteRange(int start,int end){
        if (start<0 || start>end || end>=size){
            throw new ArrayIndexOutOfBoundsException("陣列下標不一致");
        }

        for (int i = 0; i < size; i++) {
            if (i+end >size){
                mArray[i+start] = null;
            }else {
                mArray[i+start] = mArray[i+end];
            }
        }

        size -=end-start;
        Object[] newArray = new Object[size];
        for (int i = 0; i < size; i++) {
            newArray[i]  = mArray[i];
        }
        mArray = newArray;
    }

    /**
     * 若在一個條件語句中丟擲異常,則程式能被編譯,但後面的語句不會被執行。
     * @param index
     * @param message
     */
    private void isVaildIndex(int index, String message) {
        if (index < 0 || index > size) {
            throw new ArrayIndexOutOfBoundsException(message);
        }
    }
}


//Test
public class Test {

    public static void main(String[] agrs){

        MyArrayList myArrayList = new MyArrayList();  //預設初始化10

        int size = myArrayList.getSize();

//        System.out.println("長度是:"+size); //0

        //新增資料
        myArrayList.add(3);
        myArrayList.add(5);

        System.out.println("長度是:"+myArrayList.getSize()); //2

//        display(myArrayList);  //3 5

        //新增固定位置的資料
        myArrayList.addWithIndex(1,15);

//        display(myArrayList); //3 15 5

        //刪除資料
        myArrayList.delete(0);

//        display(myArrayList); //5 15

//        System.out.println(myArrayList.getSize());
        myArrayList.deleteWithIndex(1);

//        display(myArrayList);

        myArrayList.find(5,8);
        display(myArrayList);

    }

    private static void display(MyArrayList myArrayList) {
        for (int i = 0; i <myArrayList.getSize(); i++) {
            System.out.println("元素是:"+myArrayList.get(i));
        }
    }
}