數組


數組是相同類型的、用一個標識符名稱封裝到一起的一個對象序列基本類型數據序列。可以使用整型索引值訪問它們的元素(“[]”語法是訪問數組唯一的方式),並且它們的尺寸不能改變。

對象數組基本類型數組在使用上幾乎是相同的,唯一的區別就是對象數組保存的是引用,基本類型數組直接保存基本類型的值。

數組標識符其實只是個引用,指向在堆中創建的一個真實對象,這個(數組)對象用以保存指向其他對象的引用。


數組定義與初始化

數組定義

定義一個數組,只需在類型名後加上一對空方括號。

int[] a;  // 更合理,表明類型是 “一個int型數組”

或者,方括號也可以放在標識符後面。

int a[];

現在擁有的只是對數組的一個引用(已經爲該引用分配了足夠的存儲空間),並沒有給數組對象本身分配任何空間。
爲了給數組創建相應的存儲空間,必須寫初始化表達式。


數組初始化

1)花括號初始化
有一種特殊的初始化表達式,由一對花括號括起來的值組成,它必須在創建數組的地方出現(定義的同時進行初始化)

int[] a = {1,2,3,4}; 

2)new初始化
如果創建的是基本類型的數組,數組元素中的基本數據類型值會自動初始化成空值(對於數字/字符就是0,對於布爾型就是false

Random rand = new Random(47);   //Random.nextInt()方法會隨機返回0到輸入參數之間的一個值
int[] a = new int[rand.nextInt(20)];  //定義的同時進行初始化

如果創建的是非基本類型的數組,那就創建了一個引用數組。默認情況下其中所有的引用被自動初始化爲null。之後可以通過創建對象,並把對象賦值給引用來完善初始化過程。

Random rand = new Random(47);    //Random.nextInt()方法會隨機返回0到輸入參數之間的一個值
Integer[] a = new Integer[rand.nextInt(20)];  //整型的包裝器類 Integer,它是一個類而不是基本類型
for (int i = 0; i < a.length; i++)
	a[i] = rand.nextInt(500);    //創建新的Integer對象,本例是通過自動包裝機制創建的

也可以使用花括號括起來的列表來初始化對象數組。有兩種形式:

Integer[] a = {new Integer(1), new Integer(2), 3,};   //初始化列表的最後一個逗號可選
Integer[] a = new Integer[] {new Integer(1), new Integer(2), 3,};  

//Other.main(new String[]{"abc", "de"});    //String對象數組 

可變參數列表

可變參數列表可以應用於參數個數或類型未知的場合。

由於所有的類都直接或間接繼承於Object類,所以可以創建以Object數組爲參數的方法。

這裏,輸出建立的類的對象,默認行爲(如果沒有定義toString()方法的話)打印出的內容是類的名稱對象的地址


在Java SE5中,加入可變參數列表的特性,如下示:
有了可變參數,就不用再顯式地編寫數組語法了。當你指定參數時,編譯器實際上會爲你去填充數組,所以你獲取的仍舊是一個數組。也就是從元素列表到數組的自動轉換。如果本身就是個數組,編譯器就不會在其上執行任何轉換。
在這裏插入圖片描述

在可變參數列表中也可以使用Object之外類型的參數(也包括int等基本類型),如下面所有的可變參數都必須是String對象。
在這裏插入圖片描述
在這裏插入圖片描述 在這裏插入圖片描述

數組賦值

謹記:數組標識符其實只是個引用,指向在堆中創建的一個真實對象
數組賦值就是對指向數組的引用賦值使之指向另一個數組對象
在這裏插入圖片描述


多維數組

創建多維數組
可以使用花括號將每個向量分隔開:

int[][] a = {
	{1, 2, 3, }, 
	{4, 5, 6, },
};

也可以使用 new 來分配數組。在不進行顯式初始化的情況下,數組的值會被自動初始化

int [][][] a = new int[2][2][4];

粗糙數組
數組中構成矩陣的每個向量都可以具有任意的長度
在這裏插入圖片描述
在這裏插入圖片描述
二維數組獲取行數a.length
二維數組獲取列數a[i].length


Arrays類實用功能

Arrays類是數組的操作類,定義在 java.util 包中,主要功能是實現數組元素的查找、數組內容填充、排序、比較等
在這裏插入圖片描述

填充數組

Java類庫Arrays類提供 Arrays.fill(),用來填充數組。
Arrays.fill()方法作用十分有限,只能用同一個值填充各個位置,而針對對象而言,就是複製同一個引用進行填充。

使用Arrays.fill()可以填充整個數組,或者像示例最後一條語句所示,只填充數組的某個區域
在這裏插入圖片描述 在這裏插入圖片描述

複製數組

Java類庫System類提供 System.arraycopy(),用它複製數組比用for循環複製要快很多。

arraycopy() 需要的參數:源數組、從源數組什麼位置開始複製的偏移量、目標數組、從目標數組什麼位置開始複製的偏移量、需要複製的元素個數
對數組的任何越界操作都會導致異常
在這裏插入圖片描述 在這裏插入圖片描述
如果是複製對象數組,那麼只是複製了對象的引用——而不是對象本身的拷貝

注:System.arraycopy() 不會執行自動包裝和自動拆包,兩個數組必須具有相同的確切類型。


數組的比較

Java類庫Arrays類提供 Arrays.equals(),用來比較整個數組。

數組相等的條件是元素個數必須相等,並且對應位置的元素也相等。這相當於對每個元素使用equals()作比較來判斷(對於基本類型,需要使用基本類型包裝器類的equals()方法。如,對於int類型使用 Integer.equals() 作比較)。

在這裏插入圖片描述 在這裏插入圖片描述

數組元素的比較

Java有兩種方式來提供比較功能。
第一種是實現 java.lang.Comparable 接口,使類具有天生的比較能力。此接口很簡單,只有 compareTo() 一個方法。此方法接收另一個Object爲參數,如果當前對象小於參數則返回負值,如果相等則返回零,如果當前對象大於參數則返回正值

第二種是創建一個實現了 Comparator 接口的單獨的類。這個類有 compare()equals() 兩個方法。然而不一定要實現equals()方法,除非有特殊的性能需要,因爲無論何時創建一個類,都是間接繼承自Object,而Object帶有equals()方法。所以只需用默認的Object的equals()方法就可以滿足接口的要求了。


數組排序

使用 Arrays.sort() 方法,就可以對任意的基本類型數組排序;
也可以對任意的對象數組進行排序,只要 該對象實現了Comparable接口具有相關聯的Comparator
在這裏插入圖片描述在這裏插入圖片描述
注意,String排序算法依據詞典編排順序排序,所以大寫字母開頭的詞都放在前面輸出,然後纔是小寫字母開頭的詞


數組與容器


總結

本章看到了Java對尺寸固定的低級數組提供了適度的支持。這種數組強調的是性能而不是靈活性

在Java的初始版本中,尺寸固定的低級數組絕對是必需的。因爲Java早期版本中對容器的支持非常少。因此,選擇包含數組總是合理的。
其後的Java版本對容器的支持得到了明顯的改進,並且現在的容器在除了性能之外的各個方面都使得數組相形見絀。有了額外的自動包裝機制和泛型,在容器中持有基本類型就變得易如反掌了,而這也進一步促使用容器來替換數組。因爲泛型可以產生類型安全的容器,因此數組面對這一變化,已經變得毫無優勢了。


最初有關效率的論點總是很吸引人,但隨着時間的推移,我們看到了與這種思想背道而馳,向着使用像容器這類高級構件的方向的演化。


因此,容器幾乎總是更好的選擇
當你使用最近的Java版本編程時,應該 “優先選擇容器而不是數組”。只有在已證明性能成爲問題,並且切換到數組對性能提高有所幫助時,你才應該將程序重構爲使用數組。



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