Java工程師成長修煉手冊:02--數組

數組是用來存儲固定大小的同類型元素。數組是 Java 編程中最重要的數據結構之一,也是最基本的數據結構,可以通過下標訪問數值中的所有元素。

數組的特點:

● 數組可以是一維數組、二維數組或多維數組。
● 數值數組元素的默認值爲 0,而引用元素的默認值爲 null。
● 數組的索引從 0 開始,如果數組有 n 個元素,那麼數組的索引是從 0 到(n-1)。

聲明數組變量

首先必須聲明數組變量,才能在程序中使用數組。下面是聲明數組變量的語法:

int[] arrays;int arrays[];

注意:

1.首選第一種方法聲明數組。int[] arrays;
2.在聲明數組時不需要規定數組的長度,例如:

int arrays[10];    //這是錯誤的

數組初始化

數組變量的聲明,和創建數組可以用一條語句完成,如下所示:

int[] arrays = new int[n];

聲明瞭 n 個元素,每個元素初始化爲 0
也可以直接賦值

int[] arrays = {value0, value1, ..., valueN};

int[] arr1 = new int[10];
int[] arr2 = {1, 2, 3};

數組的元素是通過索引訪問的。數組索引從 0 開始,所以索引值從 0 到 arrays.length-1。
注意:數組初始化如果聲明瞭數組長度,則不能直接賦值。例如,int[] arr = new int[5]{1, 2, 3, 4, 5}; 一旦聲明瞭數組的大小,就不能再修改。

數組遍歷

數組遍歷的常見方式有三種:傳統的 for 循環、for each 遍歷、Lambda 表達式(這個是JDK8新增的,會專門用一節講解Lambda 表達式)。
方式一:傳統 for 循環

int[] arrays = {1, 2, 3};
for(int i = 0;i < arrays.length;i++){
    System.out.println(arrays[i]);
}

方式二:for each

String[] str = {"aa", "bb", "cc"};
for (String s : str) {
    System.out.println(s);
}

for each是for循環的增強版
方式三:JDK 8 中的 Lambda 表達式

int[] arrays = {1, 2, 3};
Arrays.stream(arrays).forEach(x -> System.out.println(x));

這裏簡單解釋一下,arrays數組後面的stream方法,是把數組轉化成流的形式,後面的forEach是進行遍歷。再往後,有個->函數,是從右往左運算,就跟java中的“=”賦值運算一樣。System.out.println(x)每一次輸出數組的值。

排序

(關於數組排序的,會另外一節詳細講解)
數組排序
使用 Arrays.sort() 方法

String[] str = {"aa", "cc", "bb"};
Arrays.sort(str);
System.out.println(Arrays.toString(str));

輸出結果:
[aa, bb, cc]

數組逆序
使用 org.apache.commons.lang3.ArrayUtils.reverse(arr) 方法:

int[] arr = {7, 8, 2, 16, 6, 13, 0, 9, 3};
// 先進行數組正序(排序)
Arrays.sort(arr);
// 再進行數組逆序
ArrayUtils.reverse(arr);
System.out.println(Arrays.toString(arr));

輸出結果
[16, 13, 9, 8, 7, 6, 3, 2, 0]
int[] arr = {7, 8, 2, 16, 6, 13, 0, 9, 3};

// 如果沒有進行排序,直接進行逆序
ArrayUtils.reverse(arr);
System.out.println(Arrays.toString(arr));

輸出結果如下:
[3, 9, 0, 13, 6, 16, 2, 8, 7]

多維數組

多維數組可以看成是數組的數組,比如二維數組就是一個特殊的一維數組,其中每一個元素都是一個一維數組。
聲明一個二維數組:String str[][] = new String[3][4];
創建了一個三行四列的數組
多維數組的動態初始化(以二維數組爲例)

直接爲每一維分配空間,格式如下:
type[][] typeName = new type[typeLength1][typeLength2];
type 可以爲基本數據類型和複合數據類型,typeLength1和 typeLength2 必須爲正整數,typeLength1爲行數,typeLength2爲列數。
例如:
int a[][] = new int[2][3];
初始化二維數組

我們之前使用的數組可以稱之爲一維數組,而多維數組可以理解爲數組的數組,可以用二維數組來舉例,二維數組也是一種特殊的多維數組。
比如我們聲明一個二維數組:int[][] arr = new int[2][4];
這就相當於我們創建了一個兩行四列的表,它的使用、賦值與取值,請查看下面代碼示例:

// 聲明二維數組
int[][] arr = new int[2][4];
//循環二維數組
for (int i = 0; i < arr.length; i++) {
    for (int j = 0; j < arr[0].length; j++) {
        // 二維數組賦值
        arr[i][j] = j;
    }
}
// 二維數組取值
System.out.println(arr[0][1]);
// 打印二維數組
System.out.println(Arrays.toString(arr[0]));
System.out.println(Arrays.toString(arr[1]));

以上程序執行的結果是:
1
[0, 1, 2, 3]
[0, 1, 2, 3]

數組類型轉換
字符串轉數組
使用 split 分隔字符串就形成了數組,請參考以下代碼:

String str = "laowang,stone,wanglei";
String[] arr = str.split(","); // 字符串轉數組
System.out.println(arr[0]);

數組轉字符串
使用 Arrays.toString() 方法,請參考以下代碼:

String[] arr = {"laowang", "stone", "wanglei"};
String str = Arrays.toString(arr);
System.out.println(str);

若要查看更多數組轉字符串的方式,請查看本文面試部分的介紹。
數組轉集合
使用 Arrays.asList() 方法,請參考以下代碼:

String[] strArr = {"cat", "dog"};
List list = Arrays.asList(strArr);
System.out.println(list);

集合轉數組
使用 List.toArrray() 方法,請參考以下代碼:

List<String> list = new ArrayList<String>();
list.add("cat");
list.add("dog");
// 集合轉換爲數組
String[] arr = list.toArray(new String[list.size()]);
System.out.println(Arrays.toString(arr));

相關面試題

1、數組和集合有什麼區別?
答:數組和集合的區別如下:
集合可以存儲任意類型的對象數據,數組只能存儲同一種數據類型的數據;
集合的長度是會發生變化的,數組的長度是固定的;
集合相比數組功能更強大,數組相比集合效率更高。
2、 以下代碼訪問數組元素打印的結果是多少?

int[] arr = new int[5] {1, 2, 3, 4, 5};
System.out.println(arr[4]);

答:程序編譯報錯,在 Java 中初始化數組時,如果直接給數組賦值,不能聲明數組長度;如果聲明瞭數組長度,則不能賦值給數組,否則編譯器報錯。
正確的寫法如下:

int[] arr = new int[]{1, 2, 3, 4, 5};
System.out.println(arr[4]);

輸出的結果爲:5,訪問元素從 0 開始。
3、 執行以下代碼會輸出什麼結果?

public static void main(String[] args) {
    int[] arr = {2, 3, 4, 8};
    change(arr);
    System.out.println(arr[2]);
}
private static void change(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        if (i % 2 == 0) {
            arr[i] *= i;
        }
    }
}

答:輸出的結果是 8。
題目解析:在 Java 中數組本質是引用類型,因此在調用方法中修改數組,就是對原數組本身的修改。
4、以下程序打印的結果是多少?

int[] intArr = new int[3];
String[] StrArr = new String[3];
System.out.println(intArr[1]);
System.out.println(StrArr[1]);

答:以上程序打印的結果是:0 和 null。
題目解析:new int[3] 相當於聲明瞭數組的長度爲 3,每個元素初始化爲 0,而 new String[3] 相當於聲明瞭數組的長度爲 3,每個元素初始化爲 null。
5、數組轉換字符串有哪些方式?
答:數組轉換字符串,有以下幾種方式。
方式一:遍歷拼接,完整代碼如下:

String[] arr = {"laowang", "stone", "wanglei"};
StringBuffer sb = new StringBuffer();
for (int i = 0; i < arr.length; i++) {
    sb.append(arr[i]);
    if (i != arr.length - 1)
        sb.append(",");
}
System.out.println(sb.toString());

方式二:Arrays.toString() 轉換,完整代碼如下:

String[] arr = {"laowang", "stone", "wanglei"};
String str2 = Arrays.toString(arr);
System.out.println(str2);

方式三:StringUtils.join() 轉換,完整代碼如下:

String[] arr = {"laowang", "stone", "wanglei"};
String str3 = StringUtils.join(Arrays.asList(arr), ","); // 使用英文逗號分隔
System.out.println(str3);

6、數組遍歷有哪幾種方式?
答:常見的數組遍歷有以下三種方式。

傳統 for 循環,如 for (int i = 0; i < arr.length; i++) { //...... }
for each 循環,如 for (int i : arr) { //...... }
jdk 8 Lambda 方式,如 Integer[] arr = {2, 3, 6, 7, 9}; Arrays._asList_(arr).forEach(x -> System._out_.println(x));

7、以下數組比較的結果分別是什麼?

String[] strArr = {"dog", "cat", "pig", "bird"};
String[] strArr2 = {"dog", "cat", "pig", "bird"};
System.out.println(Arrays.equals(strArr, strArr2));
System.out.println(strArr.equals(strArr2));
System.out.println(strArr == strArr2);

答:上面代碼執行的結果,分別爲:truefalsefalse

題目解析:strArr == strArr2 爲引用比較,因此結果一定是 false,而數組本身的比較也就是 strArr.equals(strArr2) 爲 false 的原因是因爲數組沒有重寫 equals 方法,因此也是引用比較。數組 equals 源碼實現如下:

public boolean equals(Object obj) {
  return (this == obj);
}

而 Arrays.equals 的結果之所以是 true 是因爲 Arrays.equals 重寫了 equals 方法。源代碼實現如下:

public static boolean equals(Object[] a, Object[] a2) {
        if (a==a2)
            return true;
        if (a==null || a2==null)
            return false;
        int length = a.length;
        if (a2.length != length)
            return false;
        for (int i=0; i<length; i++) {
            Object o1 = a[i];
            Object o2 = a2[i];
            if (!(o1==null ? o2==null : o1.equals(o2)))
                return false;
        }
        return true;
    }

本人能力有限,錯誤之處還請指出

更多後續內容及文章,百度:暗影月色程序猿

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