數(shù)組的基本概念
數(shù)組的定義:
- Java中要求所有的數(shù)組元素具有相同的數(shù)據(jù)類型。因此在一個數(shù)組中,數(shù)組元素的類型是唯一的,不能存儲多種類型的數(shù)據(jù)。
- 一旦數(shù)組的初始化完成,數(shù)組在內(nèi)存中所占的空間將被固定下來,因此數(shù)組的長度不可以被改變。即使某個數(shù)組元素的數(shù)據(jù)被清空,他占的空間依然被保留,依然屬于該數(shù)組,數(shù)組的長度依然不變。
- 值得指出的是,數(shù)組也是一種數(shù)據(jù)類型,是引用類型。所以可以把數(shù)組作為數(shù)組的元素,也就構(gòu)成了二維數(shù)組。
- 數(shù)組是相同類型數(shù)據(jù)的有序集合。數(shù)組描述的是相同類型的若干個數(shù)據(jù),按照一定的先后次序排列組合而成。其中,每一個數(shù)據(jù)稱作一個元素,每個元素可以通過一個索引(下標)來訪問它們。
- 數(shù)組名代表的是連續(xù)空間的首地址
通過首地址可以依次訪問數(shù)組所有元素
元素在數(shù)組中的排序叫做下標從零開始
數(shù)組的基本特點:
- 長度是確定的。數(shù)組一旦被創(chuàng)建,它的大小就是不可以改變的。
- 其元素必須是相同類型,不允許出現(xiàn)混合類型。元素的類型可以是java 支持的任意類型
- 數(shù)組類型可以是任何數(shù)據(jù)類型,包括基本類型和引用類型。
- 數(shù)組的元素在堆內(nèi)存中被分配空間,并且是連續(xù)分配的
- 使用new 關(guān)鍵字對數(shù)組進行 內(nèi)存的分配。每個元素都會被jvm 賦予默認值。默認規(guī)則:整數(shù):0 浮點數(shù):0.0 字符:\u0000 布爾:false 引用數(shù)據(jù)類型:null。
- 數(shù)組的元素都是有序號的,序號從0開始,0序的。稱作數(shù)組的下標、索引、角標
數(shù)組的優(yōu)缺點:
優(yōu)點:
1:可以保存若干個數(shù)據(jù)。
2:隨機訪問的效率很高。根據(jù)下標訪問元素效率高(元素連續(xù)分配空間)。
缺點:
1:數(shù)組的元素的類型必須一致。元素類型必須一致。
2:連續(xù)分配空間在堆中,如果數(shù)組的元素很多,對內(nèi)存的要求更加的嚴格。
3:根據(jù)內(nèi)容查找元素效率比較低,需要逐個比較個。
4:刪除元素、插入元素效率比較低,需要移動大量的元素。
5:數(shù)組定長,不能自動擴容。
6:數(shù)組沒有封裝,數(shù)組對象只提供了一個數(shù)組長度的屬性,但是沒有提供方法用來操作元素。
定義一個數(shù)組
數(shù)組的定義可以采用兩種方法,推薦采用第一種,這樣變量的類型是數(shù)組這一概念更加直接。
- (1) type[] arrayName;
- (2) type arrayName[];
數(shù)組是一個引用類型的變量,因此使用它定義一個變量時,僅僅表示定義了一個引用變量(也就是定義了一個指針),這個引用變量還未指向任何有效的內(nèi)存,因此定義數(shù)組時并沒有指定數(shù)組的長度,這個應(yīng)用變量并沒有指向任何有效的內(nèi)存空間,所以還不能被使用,需要對其初始化。
初始化數(shù)組
靜態(tài)初始化
- 初始化時由程序員顯示指定每個數(shù)組元素的初始值,由系統(tǒng)決定數(shù)組長度。
arrayName = new type[] {element1 , element2 , element3 , element4...};
- 此處的type必須與定義數(shù)組變量時所用的type相同,也可以是定義時的type的子類
- 執(zhí)行靜態(tài)初始化時,顯示指定的數(shù)組元素值的類型必須與new關(guān)鍵字后面的type類型相同,或者時其子類的實例。
動態(tài)初始化
- 初始化時程序員只指定數(shù)組長度,由系統(tǒng)為數(shù)組元素分配初始值。
arrayName = new type[length];
- 這個時候數(shù)組是創(chuàng)建了,里面的每一個元素都是null
public static void main(String[] arg){
String[] str = new String[10];
System.out.print(str[0]);
System.out.print(str[5]);
System.out.print(str[9]);
}
null
null
null
更簡潔的方法
- 如果我們在定義的時候就對數(shù)組進行靜態(tài)初始化,可以用一種更簡潔的方法。
type[] arrayName = {element1 , element2 , ...};
那么當數(shù)組開辟空間之后,就可以采用如下的方式的操作:
- 數(shù)組的訪問通過索引完成,即:“數(shù)組名稱[索引]”,但是需要注意的是,數(shù)組的索引從0開始,所以索引的范圍就是0 ~ 數(shù)組長度-1,例如開辟了3個空間的數(shù)組,所以可以使用的索引是:0,1,2,如果此時訪問的時候超過了數(shù)組的索引范圍,會產(chǎn)生java.lang.ArrayIndexOutOfBoundsException 異常信息;
- 當我們數(shù)組采用動態(tài)初始化開辟空間后,數(shù)組里面的每一個元素都是該數(shù)組對應(yīng)數(shù)據(jù)類型的默認值;
- 數(shù)組本身是一個有序的集合操作,所以對于數(shù)組的內(nèi)容操作往往會采用循環(huán)的模式完成,數(shù)組是一個有限的數(shù)據(jù)集合,所以應(yīng)該使用 for 循環(huán)。
- 在 Java 中提供有一種動態(tài)取得數(shù)組長度的方式:數(shù)組名稱.length;
但是千萬要記住,數(shù)組屬于引用數(shù)據(jù)類型,所以在數(shù)組使用之前一定要開辟控件(實例化),如果使用了沒有開辟空間的數(shù)組,則一定會出現(xiàn) NullPointerException 異常信息。
數(shù)組引用傳遞
既然數(shù)組屬于引用數(shù)據(jù)類型,那么也一定可以發(fā)生引用傳遞。在這之前首先來研究一下數(shù)組的空間開辟。
public class ArrayDemo {
public static void main(String args[]) {
int data[] = null;
data = new int[3]; //開辟一個長度為3的數(shù)組
data[0] = 10;
data[1] = 20;
data[2] = 30;
}
}

那么既然說到了引用數(shù)據(jù)類型了,就一定可以發(fā)生引用傳遞,而現(xiàn)在的引用傳遞的本質(zhì)也一定是:同一塊堆內(nèi)存空間可以被不同的棧內(nèi)存所指向。
public class ArrayDemo {
public static void main(String args[]) {
int data[] = null;
data = new int[3]; //開辟一個長度為3的數(shù)組
int temp[] = null; //聲明對象
data[0] = 10;
data[1] = 20;
data[2] = 30;
temp = data; //int temp[] = data;
temp[0] = 99;
for(int i = 0; i < temp.length; i++) {
System.out.println(data[i]);
}
}
}

java.util.Arrays類
DK提供的java.util.Arrays類,包含了常用的數(shù)組操作,方便我們?nèi)粘i_發(fā)。Arrays類包含了:排序、查找、填充、打印內(nèi)容等常見的操作。
toString() 日志打印
public static String toString(long[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
// 將數(shù)組的元素拼接起來了
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
sort() 排序
public static void sort(int[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}
asList() 將數(shù)組轉(zhuǎn)換成集合
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
copyOf() 復(fù)制一份
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}