博主今天去了一個java的實習面試,發現有好多java最基礎的數據結構對於博主來說反而感到陌生,在面試官問一些常見的例如HashMap這樣的數據結構,博主能回答的頭頭是道,但是在問到Array和ArrayList的區別和聯繫之後,卻讓博主一臉懵。好吧,不多說,現在特此整理。 首先, Array是ja ...
博主今天去了一個java的實習面試,發現有好多java最基礎的數據結構對於博主來說反而感到陌生,在面試官問一些常見的例如HashMap這樣的數據結構,博主能回答的頭頭是道,但是在問到Array和ArrayList的區別和聯繫之後,卻讓博主一臉懵。好吧,不多說,現在特此整理。
首先, Array是java中的數組,我們聲明java的數組有三種方式:
1 int[] a = new int[10]; 2 int a[] = new int[10]; //這種方式同c語言一樣 3 int a[] = {1,2,3,4};
從上面的聲明中可以看出來,我們在定義了一個數組的時候,必須指定這個數組的數據類型,也就是說,數組是相同數據類型的集合。另外,在數組聲明的時候,我們也聲明瞭數組的大小,數組的元素個數是固定的。
下麵,我們看看數組的應用:
1 import java.util.Arrays; 2 3 /** 4 * @author jy 5 * @time 下午7:59:26 6 */ 7 public class ArrayAndArrayList { 8 public static void main(String[] args) { 9 10 int a[] = new int[4]; 11 System.out.println(a.length); //數組的長度屬性 12 13 int b[] = {1,2}; 14 int c[] = {1,2}; 15 System.out.println(b.equals(c)); //輸出為false,可見數組並沒有重寫hashcode()和equals()方法 16 System.out.println(Arrays.equals(b, c)); //利用java.util.Array的equals()來判斷數組是否相等,這裡輸出true 17 System.out.println(isEquals(b,c)); 18 19 } 20 21 /** 22 * 重寫方法來手動實現數組之間的比較方法 23 */ 24 public static boolean isEquals(int[] b, int[] c) { 25 26 if(b == null || c == null){ 27 return false; 28 } 29 if(b.length != c.length){ 30 return false; 31 } 32 for (int i = 0; i < c.length; i ++) { 33 if(b[i] != c[i]){ 34 return false; 35 } 36 } 37 return true; 38 } 39 40 }
可見,數組的長度是固定的,不可變的。數組並未重寫object的hashcCode()和equals()方法。
我們都知道,數組還可以是二維的,下麵我們看看二維數組是如何聲明的:
1 int[][] da = new int[2][3]; //推薦用這種聲明方式,更能表明數組的類型 2 int db[][] = new int[4][3];
但是,有一種變長的二維數組:
1 int[][] dc = new int[2][]; //第一維的大小不能空缺,第二維的大小可以是不一樣的。 2 dc[0] = new int[2]; 3 dc[1] = new int[3];
好了,數組這個基本的數據結構的應用我們就說到這裡,為了突出主題,其餘的一些不相干的應用我們就不扯了。
下麵,我們再來看看ArrayList這個集合:
ArrayList是動態數組,也就是數組的複雜版本,它可以動態的添加和刪除元素,ArrayList實現了java.util.Collections.Collection.List介面。下麵我們來看一下最基本的聲明:
ArrayList list = new ArrayList(10); ArrayList<Integer> list1 = new ArrayList<Integer>();
第一種聲明中,在不使用泛型的情況下,這個list是可以添加進不同類型的元素的,而且arraylist是可以不用指定長度的。在使用泛型時,我們就只能添加一種類型的數據了。
ArrayList的重要方法和屬性如下代碼所示:
1 ArrayList<Integer> list = new ArrayList<Integer>(); 2 list.add(1); 3 list.add(2); 4 list.add(3); 5 list.remove(1); 6 Object[] p = list.toArray(); //轉化成數組 7 System.out.println(p[0]); 8 System.out.println(list.contains(4)); //是否包含某個元素 9 System.out.println(list.size()); //list的長度 10 System.out.println(list.get(0)); //按位獲取list中的元素
11 list.trimToSize(); //這個方法用於將ArrayList固定到實際元素的大小,當動態數組元素確定不在添加的時候,可以調用這個方法來釋放空餘的記憶體
上面顯示了ArrayList的一些重要的方法。下麵我們就這兩個集合類進行對比:
(1)ArrayList是Array的複雜版本
ArrayList內部封裝了一個Object類型的數組,從一般的意義來說,它和數組沒有本質的差別,甚至於ArrayList的許多方法,如Index、IndexOf、Contains、Sort等都是在內部數組的基礎上直接調用Array的對應方法。
(2)存儲的數據類型
ArrayList可以存儲異構對象,而Array只能存儲相同數據類型的數據。
(3)長度的可變
Array的長度實際上是不可變的,二維變長數組實際上的長度也是固定的,可變的只是其中元素的長度。而ArrayList的長度既可以指定(即使指定了長度,也會自動2倍擴容)也可以不指定,是變長的。
(4)存取和增刪元素
對於一般的引用類型來說,這部分的影響不是很大,但是對於值類型來說,往ArrayList裡面添加和修改元素,都會引起裝箱和拆箱的操作,頻繁的操作可能會影響一部分效率。另外,ArrayList是動態數組,它不包括通過Key或者Value快速訪問的演算法,所以實際上調用IndexOf、Contains等方法是執行的簡單的迴圈來查找元素,所以頻繁的調用此類方法並不比你自己寫迴圈並且稍作優化來的快,如果有這方面的要求,建議使用Hashtable或SortedList等鍵值對的集合。
好了,關於這兩個數據結構的對比我們就到這裡,如果有覺得不妥的地方,歡迎大家指正。
另外,這是我第一次寫博客,求輕噴。