自制數組隊列 同 系統庫中的ArrayList 方法性能對比

需要傳入數組大小
定義了頭指針和尾指針

我的:
	public int Maxsize;
	private int front;
	private int rear;
	private Object[] Arr;

	public ArrQueue(int ArrMaxsize) {
		Maxsize = ArrMaxsize;
		Arr = new Object[Maxsize];
		front = -1;
		rear = -1;
	}

最初,頭指針和尾指針都指向-1在這裏插入圖片描述

Java jdk:
//它也是傳入數組的大小,並且有異常提示
public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

入隊

我的:
public void In_ArrQueue(Object obj){
    	if(rear >= Maxsize-1){	//超界
    		System.out.println("隊滿!!!");
    	}
    	else{
    		rear++;		//隊尾指針上移
    		Arr[rear] = obj;	//元素加到隊尾(後進後出)
    	}
    }

Java jdk包裏面的就牛逼了,它用到了資源申請算法。。。

Java jdk:
public boolean add(E e) {
    ensureCapacityInternal(size + 1);
    elementData[size++] = e;	//元素入隊
	return true;
}

////////後面的一大堆方法全是關於申請合理的數組容量的

private static final int DEFAULT_CAPACITY = 10;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

//minCapacity 就是需要的最小的容量
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {	//若數組爲空
		minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);	//分配大小爲10
    }
	ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
	if (minCapacity - elementData.length > 0)	//需要的容量比擁有的大(添加數組後若越界)
        grow(minCapacity);		//增加擁有的容量
}

private void grow(int minCapacity) {
	int oldCapacity = elementData.length;
	
    int newCapacity = oldCapacity + (oldCapacity >> 1);		//相當於oldCapacity的1.5倍
    if (newCapacity - minCapacity < 0)	//如果新容量比需要的還要小
        newCapacity = minCapacity;	//賦值
    if (newCapacity - MAX_ARRAY_SIZE > 0)	//合理性檢查
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}

private static int hugeCapacity(int minCapacity) {	//檢測異常
	//小於0代表minCapacity溢出
	if (minCapacity < 0)
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}

下面來對比一下性能(莫名感覺很慚愧。。。):

//仍然是比較加入一千萬個點的時間
public static void main(String[] args) {
		long S = 0;
		for (int n = 0; n < 10; n++) {
			long start = System.currentTimeMillis();
			ArrayList<Object> arrayList = new ArrayList<>();
			for (int i = 0; i < 10000000; i++) {
				arrayList.add(i);
			}
			long end = System.currentTimeMillis();
			System.out.println(end - start);
			long S1 = end - start;
			S = S + S1;
		}
		System.out.println("平均時間" + S / 10);

我的:
在這裏插入圖片描述
系統:
在這裏插入圖片描述

  • 我的add方法之所以快,是因爲我一開始就定義好了數組的長度,這樣其實是浪費了大量的空間
  • 系統通過資源申請算法,很完美的控制了空間資源分配,實現了利用數組創建隊列不需要定義長度
  • (今天的操作系統課剛好講了銀行家算法中的資源請求算法,這就用上了,,,)

出隊

我的:
public void Out_ArrQueue(){
		if(rear == front){
			System.out.println("隊空!!!");
		}
		else{
			front++;	//出隊時隊首指針上移	(假溢出的部分根源)
			Arr[front]=null;
		}
	}
Java jdk:
E elementData(int index) {	//返回index位置的元素
        return (E) elementData[index];
    }

private void rangeCheck(int index) {	//檢測範圍異常
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    
public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

public E remove(int index) {	//jdk中要傳入一個下標
	rangeCheck(index);	//是否超界
    modCount++;
    E oldValue = elementData(index);		//獲取該位置元素

    int numMoved = size - index - 1;	//被刪除位置的元素之後的元素要前移
    if (numMoved > 0)
		System.arraycopy(elementData, index+1, elementData, index, numMoved);	//拷貝移動元素
    elementData[--size] = null;	//如果後面沒要移的元素,說明是個尾節點

    return oldValue;	//返回要刪除的值(Object a = arrayList.remove(i))
}

分析完系統的代碼,下面的測試根本就沒有必要去測了,,,我感覺無比慚愧,自己寫的代碼就是渣。。。
我的運行時間(一千萬數):
在這裏插入圖片描述
系統運行時間(十萬個數):
在這裏插入圖片描述

  • 系統是從指定位置刪除元素的

查詢

我的:
public void Find(int index){
		System.out.println(Arr[index]);
	}
Java jdk:
public E get(int index) {
	rangeCheck(index);	//檢測是否越界
    return elementData(index);	//返回值
}
  • 查詢功能,因爲大家用的都是數組,所以就比較簡單,查詢就很快
  • Java jdk多了一個檢測異常
  • 以後寫代碼儘量養成這種檢測異常的習慣

一千萬個點:
在這裏插入圖片描述

添加元素,利用了資源申請算法
刪除元素,系統可以從指定位置刪除
每一種方法,系統都有異常檢測

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