數組的聲明與初始化

數組是Java中存儲多個相同類型數據的容器,你可以把它想象成一排整齊的抽屜,每個抽屜只能放特定類型的數據。在Java中聲明和初始化數組有三種常用方式,我們通過學生成績管理的場景來理解:

靜態初始化:已知所有元素值時使用

當你已經明確知道每個位置的元素值時,直接在創建數組時賦值:

複製

// 聲明並初始化一個存儲5名學生成績的數組
int[] scores = {90, 85, 95, 88, 92};
System.out.println("數組長度:" + scores.length); // 輸出:數組長度:5
System.out.println("第一個學生成績:" + scores[0]); // 輸出:第一個學生成績:90

這種方式會自動根據提供的元素數量確定數組長度,注意數組索引從0開始,就像我們數東西從第1個開始,但計算機從0開始計數。

動態初始化:已知長度但元素值需後續確定

當你知道需要存儲多少個數據,但具體值還不確定時(比如需要從鍵盤輸入):

複製

// 創建一個能存儲3門課程名稱的數組,初始值為null
String[] courses = new String[3];
// 後續為數組元素賦值
courses[0] = "Java基礎";
courses[1] = "數據結構";
courses[2] = "數據庫原理";

// 嘗試訪問不存在的索引會報錯
// System.out.println(courses[3]); // 此行會拋出ArrayIndexOutOfBoundsException

這裏new String[3]告訴JVM創建一個長度為3的字符串數組,每個元素初始為null。

默認初始化:數組作為成員變量時的隱式初始化

當數組作為類的成員變量時,JVM會自動為其初始化默認值:

複製

public class Student {
    // 成員變量數組會被默認初始化
    private int[] ages; // int類型數組默認值為0

    public void printAges() {
        ages = new int[2]; // 動態初始化後
        System.out.println("默認值:" + ages[0]); // 輸出:默認值:0
    }

    public static void main(String[] args) {
        new Student().printAges();
    }
}

不同數據類型的默認值不同:整數類型為0,浮點類型為0.0,布爾類型為false,引用類型為null。

數組訪問與遍歷

數組索引規則

數組元素通過索引訪問,就像通過抽屜編號找到對應的抽屜。Java數組的索引從0開始,最大索引為數組長度-1。例如長度為5的數組,有效索引是0-4。

數組內存結構

理解數組在內存中的存儲方式有助於避免常見錯誤:

Java21天學習計劃 - 第四天:數組與字符串基礎_數組

從圖中可以看到:

  • 數組變量(如a)存儲在棧內存中,指向堆內存中的實際數組對象
  • 數組長度(a.length)是數組對象的屬性,對於二維數組a[0].length表示第一個子數組的長度
  • 數組元素在堆內存中連續存儲,通過索引快速訪問

遍歷數組的兩種方式

1. 普通for循環:需要索引時使用

複製

int[] numbers = {2, 4, 6, 8, 10};
// 計算數組所有元素的和
int sum = 0;
for (int i = 0; i < numbers.length; i++) {
    sum += numbers[i];
    System.out.println("索引" + i + "的值:" + numbers[i]);
}
System.out.println("數組元素總和:" + sum); // 輸出:數組元素總和:30

2. 增強for循環(for-each):僅遍歷元素時使用

複製

String[] fruits = {"蘋果", "香蕉", "橙子"};
System.out.println("水果列表:");
for (String fruit : fruits) { // 讀作"for each fruit in fruits"
    System.out.println(fruit);
}

運行結果:

複製

水果列表:
蘋果
香蕉
橙子

增強for循環的優點是代碼簡潔,無需關心索引,但缺點是無法獲取當前元素的索引位置。

多維數組

多維數組可以理解為"數組的數組",最常用的是二維數組,類似於表格或Excel工作表。

二維數組的聲明與初始化

複製

// 方式1:靜態初始化一個3行2列的二維數組
int[][] matrix = {
    {1, 2},
    {3, 4},
    {5, 6}
};

// 方式2:動態初始化一個2行3列的二維數組
int[][] scores = new int[2][3];
scores[0][0] = 90; // 第1個學生第1門課成績
scores[0][1] = 85; // 第1個學生第2門課成績
scores[0][2] = 92; // 第1個學生第3門課成績
scores[1][0] = 88; // 第2個學生第1門課成績
// ...以此類推

二維數組的遍歷

使用嵌套循環遍歷二維數組:

複製

// 遍歷matrix數組並打印
for (int i = 0; i < matrix.length; i++) { // 外層循環控制行數
    for (int j = 0; j < matrix[i].length; j++) { // 內層循環控制列數
        System.out.print(matrix[i][j] + " ");
    }
    System.out.println(); // 每行結束換行
}

運行結果:

複製

1 2
3 4
5 6

注意:Java中的二維數組可以是不規則的,即每行的列數可以不同:

複製

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

字符串創建與常用方法

字符串是Java中最常用的類之一,用於表示文本數據。Java提供了String、StringBuffer和StringBuilder三個類來處理字符串,它們各有特點:

  • String:不可變字符串,適合內容不常變化的場景
  • StringBuffer:可變字符串,線程安全,性能稍低
  • StringBuilder:可變字符串,非線程安全,性能高(推薦單線程環境使用)

String類的常用方法

Java21天學習計劃 - 第四天:數組與字符串基礎_System_02

以下是實際開發中最常用的String方法:

複製

String str = "  Hello Java World  ";

// 1. 獲取字符串長度
System.out.println("長度:" + str.length()); // 輸出:長度:16

// 2. 去除首尾空格
String trimmed = str.trim();
System.out.println("去除空格後:'" + trimmed + "'"); // 輸出:去除空格後:'Hello Java World'

// 3. 字符串截取
String sub = str.substring(2, 7); // 從索引2開始到7(不包含7)
System.out.println("截取結果:" + sub); // 輸出:截取結果:Hello

// 4. 字符串查找
int index = str.indexOf("Java");
System.out.println("Java的位置:" + index); // 輸出:Java的位置:7

// 5. 字符串替換
String replaced = str.replace("Java", "Programming");
System.out.println("替換後:" + replaced); // 輸出:替換後:  Hello Programming World

// 6. 大小寫轉換
System.out.println("小寫:" + str.toLowerCase());
System.out.println("大寫:" + str.toUpperCase());

// 7. 字符串比較
String s1 = "Hello";
String s2 = "hello";
System.out.println("是否相等(區分大小寫):" + s1.equals(s2)); // false
System.out.println("是否相等(不區分大小寫):" + s1.equalsIgnoreCase(s2)); // true

StringBuilder的使用

當需要頻繁修改字符串內容時,使用StringBuilder效率更高:

複製

// 創建StringBuilder對象
StringBuilder sb = new StringBuilder();

// 追加內容
sb.append("Hello");
sb.append(" ");
sb.append("World");
sb.append("!");

// 插入內容
sb.insert(5, " Java"); // 在索引5處插入

// 轉換為String
String result = sb.toString();
System.out.println(result); // 輸出:Hello Java World!

數組與字符串轉換

在實際開發中,經常需要在數組和字符串之間進行轉換,Java提供了便捷的方法:

字符串轉數組:String.split()

複製

String str = "apple,banana,orange";
// 使用逗號分割字符串
String[] fruits = str.split(",");

System.out.println("分割後的數組:");
for (String fruit : fruits) {
    System.out.println(fruit);
}

運行結果:

複製

分割後的數組:
apple
banana
orange

數組轉字符串:Arrays.toString()

複製

import java.util.Arrays; // 需要導入Arrays類

int[] numbers = {1, 2, 3, 4, 5};
// 將數組轉換為字符串
String arrayStr = Arrays.toString(numbers);
System.out.println("數組轉字符串:" + arrayStr); // 輸出:數組轉字符串:[1, 2, 3, 4, 5]

字符數組與字符串互轉

複製

// 字符串轉字符數組
String str = "Hello";
char[] chars = str.toCharArray();
System.out.println("字符數組長度:" + chars.length); // 輸出:字符數組長度:5

// 字符數組轉字符串
char[] charArray = {'W', 'o', 'r', 'l', 'd'};
String newStr = new String(charArray);
System.out.println("新字符串:" + newStr); // 輸出:新字符串:World

常見異常處理

在使用數組和字符串時,初學者最容易遇到兩種異常:數組越界異常和空指針異常。

數組越界異常

Java21天學習計劃 - 第四天:數組與字符串基礎_System_03

產生原因:訪問了超出數組索引範圍的位置。

複製

int[] numbers = {1, 2, 3};
System.out.println(numbers[3]); // 錯誤!數組長度為3,有效索引是0-2

運行結果

複製

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
    at ArrayExample.main(ArrayExample.java:5)

規避方法:使用數組時始終確保索引在0到array.length - 1範圍內:

複製

int[] numbers = {1, 2, 3};
// 安全的循環方式
for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]);
}

空指針異常

Java21天學習計劃 - 第四天:數組與字符串基礎_數組_04

產生原因:當一個對象為null時,調用其方法或訪問其屬性。

複製

String str = null;
System.out.println(str.length()); // 錯誤!str為null,沒有length()方法

運行結果

複製

Exception in thread "main" java.lang.NullPointerException
    at StringExample.main(StringExample.java:3)

規避方法:使用對象前先檢查是否為null:

複製

String str = null;
// 安全的處理方式
if (str != null) {
    System.out.println(str.length());
} else {
    System.out.println("字符串為空");
}

實踐案例

案例一:數組排序

使用Arrays.sort()方法對數組進行排序,這是開發中最常用的排序方式:

Java21天學習計劃 - 第四天:數組與字符串基礎_數組_05

複製

import java.util.Arrays;

public class ArraySortExample {
    public static void main(String[] args) {
        // 定義一個無序數組
        int[] scores = {85, 92, 78, 90, 88};

        System.out.println("排序前:" + Arrays.toString(scores));

        // 排序數組(默認升序)
        Arrays.sort(scores);

        System.out.println("排序後:" + Arrays.toString(scores));

        // 查找最高分(排序後最後一個元素)
        System.out.println("最高分:" + scores[scores.length - 1]);

        // 查找最低分(排序後第一個元素)
        System.out.println("最低分:" + scores[0]);
    }
}

運行結果:

複製

排序前:[85, 92, 78, 90, 88]
排序後:[78, 85, 88, 90, 92]
最高分:92
最低分:78

案例二:字符串反轉

實現字符串反轉有多種方式,這裏介紹兩種常用方法:

Java21天學習計劃 - 第四天:數組與字符串基礎_字符串_06

方法一:使用StringBuilder的reverse()方法(推薦)

複製

public class StringReverseExample {
    public static void main(String[] args) {
        String original = "Hello Java";

        // 方法一:使用StringBuilder
        StringBuilder sb = new StringBuilder(original);
        String reversed1 = sb.reverse().toString();

        System.out.println("原字符串:" + original);
        System.out.println("反轉後(方法一):" + reversed1);

        // 方法二:使用字符數組
        char[] chars = original.toCharArray();
        String reversed2 = reverseWithArray(chars);
        System.out.println("反轉後(方法二):" + reversed2);
    }

    // 使用字符數組手動反轉
    private static String reverseWithArray(char[] chars) {
        int left = 0;
        int right = chars.length - 1;

        while (left < right) {
            // 交換左右兩個字符
            char temp = chars[left];
            chars[left] = chars[right];
            chars[right] = temp;

            // 移動指針
            left++;
            right--;
        }

        return new String(chars);
    }
}

運行結果:

複製

原字符串:Hello Java
反轉後(方法一):avaJ olleH
反轉後(方法二):avaJ olleH

總結與練習

今天我們學習了Java中數組和字符串的基礎知識,包括:

  1. 數組:聲明初始化、訪問遍歷、多維數組
  2. 字符串:String類常用方法、StringBuilder使用
  3. 轉換技巧:數組與字符串的相互轉換
  4. 異常處理:數組越界和空指針異常的規避
  5. 實踐案例:數組排序和字符串反轉

練習題

  1. 數組統計:創建一個int數組,統計其中偶數和奇數的個數。
  2. 字符串處理:編寫一個方法,將字符串中的每個單詞首字母大寫。
  3. 綜合練習:從控制枱輸入5個整數,排序後輸出,並計算平均值。

通過這些基礎知識的學習,你已經具備了處理批量數據和文本的能力,這是Java編程的重要基礎。明天我們將學習面向對象編程的基礎知識,進一步提升你的Java技能!