在Java中,作為所有數據結構中存儲和獲取速度最快的一種,數組憑借其這種簡單易用的優勢在各個方面都能大顯神威。但是數組也有自身的局限性。數組的長度必須是固定的一旦定義之后就無法動態的更改,這就會造成這樣的問題,如果數組已滿,就無法繼續添加數據(當然你可以定義一個“足夠大的數組”,但問題是多大才是足夠大呢?太小不夠,太大浪費內存空間)。如果刪除一個數據,它的內存空間空着沒有被使用。另外數組只能存儲同一類型的數據,如果把它設置成Object類型的話,是可以存不同類型的數據了,但是設想這樣一種情況:現在項目中有定義了一個Object類型的數組。項目中擁有很多的圖形類,確實這個數組都能保存,但問題是這時用戶保存了一個其他類型的東西,程序是不會報錯的,因為類型是Object。這樣肯定是不行的。另外在Java中向上轉型是安全的,Object類型可以適應一切類型,但是向下轉型確是不安全的。比如下面的代碼:

1 package Cbs; 2
3 public class Test { 4
5 public static void main(String[] args) { 6 //定義Object類型的數組
7 Object[] array=new Object[10]; 8 //使用基本數據類型的包裝類
9 Integer i=10; 10 Float f=12.0f; 11 //向上轉型,沒有問題
12 array[0]=i; 13 array[1]=f; 14 //向下轉型
15 int i1=(int)array[0]; 16 //注意array[1]中存儲的是12.0,但是這樣子語法沒有問題,編譯不會出錯
17 int i2=(int)array[1]; 18 System.out.println(i1); 19 System.out.println(i2);//拋出ClassCastException異常
20 } 21
22 }
也就是說,如果使用這樣的數組,在轉型是發生問題是很難發現的。這也是數組的一個局限性。
那么既然數組存在這樣的缺陷,我們就要想辦法解決這個問題。該如何解決呢?數組長度當然是無法發生變化的,但是數組名里面存儲的是數組在內存中的首地址這個確是可以改變的。那么是否可以通過地址的改變來動態改變數組的大小呢?答案是肯定的。我們可以聲明一個新的數組,把它的大小增加到我們想要的程度,然后把原數組的值copy到新數組中,再把新數組賦值給原數組,這樣操作就可以使得數組的大小發生動態改變了。這時增加一個數據就讓新數組長度加一,減少一個數據,就讓新數組長度減一就可以了。數組長度的問題就解決了。那么數據類型應該如何解決呢?這就要使用Java的泛型搞定了。泛型Java中並不是一種數據類型,而是一個用於表示類型的符號,常用的泛型表示符號有E、K、Y等。這樣我們在定義類的時候就可以指定泛型,然后在類中使用指定的類型返回和輸入,這樣就不會產生類型的問題了。下面要做的就是定義一個類,用於操作數組,也就是我們要講的數組隊列。

1 package com.cbs; 2
3 /**
4 * 自定義數組隊列 5 * @author CBS 6 */
7
8 public class MyList<E> {//使用泛型E 9 //聲明一個Object數組
10 private Object[] array; 11 private int size=0;//記錄隊列中數據類型的長度
12 private int initCount=0;//初始化時數組的大小,默認為0
13 private int incresCount=1;//數組已滿時,每次數組的增長長度
14 /**
15 * 構造方法 16 * @param initCount 為數組的初始長度 17 */
18 public MyList(int initCount){ 19 this.initCount=initCount; 20 array=new Object[initCount]; 21 } 22 /**
23 * 構造方法 24 * @param initCount 為數組的初始長度 25 * @param incresCount 為數組滿是每次的增長長度 26 */
27 public MyList(int initCount, int incresCount) { 28 this.initCount = initCount; 29 this.incresCount = incresCount; 30 array=new Object[initCount]; 31 } 32
33 //實現數據的添加
34 public void add(E e){ 35 if(size<initCount){ 36 array[size]=e; 37 } 38 else{ 39 Object[] newArray=new Object[array.length+incresCount]; 40 newArray[size]=e; 41 for(int i=0;i<array.length;i++){ 42 newArray[i]=array[i]; 43 } 44 initCount+=incresCount; 45 array=newArray; 46 } 47 size++; 48 } 49 //實現刪除指定下標位置的數據
50 public void delete(int i){ 51 size--; 52 initCount--; 53 Object[] newArray=new Object[array.length-1]; 54 for(int j=0;j<i;j++) 55 newArray[j]=array[j]; 56 for(int j=i+1;j<array.length;j++) 57 newArray[j-1]=array[j]; 58 array=newArray; 59 } 60 //實現插入指定下標位置的數據
61 public void insert(E e,int i){ 62 if(size<initCount && i>=0 && i<size-1){ 63 for(int j=size;j>i;j--) 64 array[j]=array[j-1]; 65 array[i]=e; 66 } 67 else{ 68 Object[] newArray=new Object[array.length+incresCount]; 69 for(int j=0;j<array.length;j++){ 70 newArray[j]=array[j]; 71 } 72 initCount+=incresCount; 73 array=newArray; 74 for(int j=size;j>i;j--) 75 array[j]=array[j-1]; 76 array[i]=e; 77 } 78 size++; 79 } 80 //實現獲取指定下標位置的數據
81 public E get(int i){ 82 if(i<0 || i>=size) 83 return null; 84 else
85 return (E) array[i]; 86 } 87 //實現更新指定下標位置的數據
88 public void upDate(E e,int i){ 89 if(i>=0 && i<size) 90 array[i]=e; 91 } 92 //獲取數組隊列中存儲的元素個數
93 public int legnth(){ 94 return size; 95 } 96
97 }
這樣一個自定義的數組對列就完成了。當然這里對自定義的數組對列做了一定的優化,可以由用戶指定初始的隊列長度和每次隊滿時增長的長度。相比於上面所說的每次長度加一,這樣做就不用每次都新建一個新的數組了。這樣以后只要在類中實例化MyList的對象就可以很方便的操作數組隊列啦。