自制数组队列 同 系统库中的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多了一个检测异常
  • 以后写代码尽量养成这种检测异常的习惯

一千万个点:
在这里插入图片描述

添加元素,利用了资源申请算法
删除元素,系统可以从指定位置删除
每一种方法,系统都有异常检测

发布了45 篇原创文章 · 获赞 14 · 访问量 2491

猜你喜欢

转载自blog.csdn.net/qq_44357371/article/details/102733228