小熊奶糖(BearCandy)
小熊奶糖(BearCandy)
发布于 2025-10-11 / 0 阅读
0
0

Java 数组详解

Java 数组详解

1. 数组基础概念

1.1 什么是数组

数组是Java中用来存储固定大小的同类型元素的线性数据结构。数组在内存中是连续分配的。

1.2 数组特点

  • 固定长度,一旦创建不能改变大小
  • 所有元素类型相同
  • 通过索引访问,索引从0开始
  • 可以是基本数据类型或引用类型

2. 数组的声明和初始化

2.1 声明数组

// 方式1:数据类型[] 数组名
int[] numbers;
String[] names;

// 方式2:数据类型 数组名[] (不推荐)
int numbers[];

2.2 初始化数组

// 1. 动态初始化 - 先声明,后分配空间
int[] arr1;
arr1 = new int[5]; // 创建长度为5的int数组

// 2. 静态初始化 - 声明时直接赋值
int[] arr2 = {1, 2, 3, 4, 5};
int[] arr3 = new int[]{1, 2, 3, 4, 5};

// 3. 默认值初始化
int[] arr4 = new int[3]; // 所有元素默认为0
boolean[] flags = new boolean[3]; // 所有元素默认为false
String[] strs = new String[3]; // 所有元素默认为null

3. 数组的常用属性

3.1 length 属性

int[] numbers = {1, 2, 3, 4, 5};
System.out.println("数组长度: " + numbers.length); // 输出: 5

// 遍历数组的常用方式
for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]);
}

4. 数组的常用操作和方法

4.1 基本操作

// 创建和访问
int[] scores = {85, 92, 78, 96, 88};

// 访问元素
System.out.println("第一个元素: " + scores[0]); // 85
System.out.println("最后一个元素: " + scores[scores.length - 1]); // 88

// 修改元素
scores[2] = 90; // 将第三个元素从78改为90

// 遍历数组 - 传统for循环
for (int i = 0; i < scores.length; i++) {
    System.out.println("索引 " + i + ": " + scores[i]);
}

// 遍历数组 - 增强for循环
for (int score : scores) {
    System.out.println("分数: " + score);
}

4.2 使用Arrays工具类

import java.util.Arrays;

public class ArrayMethodsExample {
    public static void main(String[] args) {
        int[] arr1 = {5, 2, 8, 1, 9};
        int[] arr2 = {1, 2, 3, 4, 5};
      
        // 1. Arrays.toString() - 数组转字符串
        System.out.println("数组内容: " + Arrays.toString(arr1));
      
        // 2. Arrays.sort() - 数组排序
        Arrays.sort(arr1);
        System.out.println("排序后: " + Arrays.toString(arr1));
      
        // 3. Arrays.binarySearch() - 二分查找(必须先排序)
        int index = Arrays.binarySearch(arr1, 8);
        System.out.println("元素8的索引: " + index);
      
        // 4. Arrays.equals() - 比较数组是否相等
        System.out.println("数组相等: " + Arrays.equals(arr1, arr2));
      
        // 5. Arrays.copyOf() - 复制数组
        int[] arr3 = Arrays.copyOf(arr1, arr1.length);
        System.out.println("复制数组: " + Arrays.toString(arr3));
      
        // 6. Arrays.copyOfRange() - 复制指定范围
        int[] arr4 = Arrays.copyOfRange(arr1, 1, 4);
        System.out.println("范围复制: " + Arrays.toString(arr4));
      
        // 7. Arrays.fill() - 填充数组
        int[] arr5 = new int[5];
        Arrays.fill(arr5, 10);
        System.out.println("填充后: " + Arrays.toString(arr5));
    }
}

4.3 多维数组

// 二维数组的声明和初始化
int[][] matrix1 = new int[3][3]; // 3x3矩阵
int[][] matrix2 = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// 访问二维数组元素
System.out.println("第二行第三列: " + matrix2[1][2]); // 6

// 遍历二维数组
for (int i = 0; i < matrix2.length; i++) {
    for (int j = 0; j < matrix2[i].length; j++) {
        System.out.print(matrix2[i][j] + " ");
    }
    System.out.println();
}

// 不规则数组
int[][] irregularArray = new int[3][];
irregularArray[0] = new int[2];
irregularArray[1] = new int[3];
irregularArray[2] = new int[1];

5. 数组的实用工具方法

5.1 自定义数组工具类

public class ArrayUtils {
  
    // 查找最大值
    public static int findMax(int[] arr) {
        if (arr == null || arr.length == 0) {
            throw new IllegalArgumentException("数组不能为空");
        }
        int max = arr[0];
        for (int num : arr) {
            if (num > max) {
                max = num;
            }
        }
        return max;
    }
  
    // 查找最小值
    public static int findMin(int[] arr) {
        if (arr == null || arr.length == 0) {
            throw new IllegalArgumentException("数组不能为空");
        }
        int min = arr[0];
        for (int num : arr) {
            if (num < min) {
                min = num;
            }
        }
        return min;
    }
  
    // 计算平均值
    public static double calculateAverage(int[] arr) {
        if (arr == null || arr.length == 0) {
            throw new IllegalArgumentException("数组不能为空");
        }
        int sum = 0;
        for (int num : arr) {
            sum += num;
        }
        return (double) sum / arr.length;
    }
  
    // 反转数组
    public static void reverse(int[] arr) {
        if (arr == null) return;
      
        int left = 0;
        int right = arr.length - 1;
        while (left < right) {
            // 交换元素
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
  
    // 查找元素索引
    public static int indexOf(int[] arr, int target) {
        if (arr == null) return -1;
      
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == target) {
                return i;
            }
        }
        return -1;
    }
}

5.2 使用示例

public class ArrayDemo {
    public static void main(String[] args) {
        int[] numbers = {23, 45, 12, 67, 89, 34};
      
        // 使用自定义工具类
        System.out.println("最大值: " + ArrayUtils.findMax(numbers));
        System.out.println("最小值: " + ArrayUtils.findMin(numbers));
        System.out.println("平均值: " + ArrayUtils.calculateAverage(numbers));
      
        System.out.println("反转前: " + Arrays.toString(numbers));
        ArrayUtils.reverse(numbers);
        System.out.println("反转后: " + Arrays.toString(numbers));
      
        // 查找元素
        int index = ArrayUtils.indexOf(numbers, 67);
        System.out.println("67的索引: " + index);
      
        // 数组拷贝的注意事项
        int[] original = {1, 2, 3};
        int[] shallowCopy = original; // 浅拷贝
        int[] deepCopy = Arrays.copyOf(original, original.length); // 深拷贝
      
        original[0] = 100;
        System.out.println("浅拷贝受影响: " + shallowCopy[0]); // 100
        System.out.println("深拷贝不受影响: " + deepCopy[0]); // 1
    }
}

6. 数组的注意事项和最佳实践

6.1 常见错误

// 1. 数组越界
int[] arr = {1, 2, 3};
// System.out.println(arr[3]); // ArrayIndexOutOfBoundsException

// 2. 空指针异常
int[] nullArray = null;
// System.out.println(nullArray.length); // NullPointerException

// 3. 类型不匹配
// String[] strs = {1, 2, 3}; // 编译错误

6.2 最佳实践

public class ArrayBestPractices {
    public static void main(String[] args) {
        // 1. 总是检查数组是否为null
        int[] arr = null;
        if (arr != null && arr.length > 0) {
            System.out.println("数组安全访问");
        }
      
        // 2. 使用增强for循环避免索引错误
        int[] numbers = {1, 2, 3, 4, 5};
        for (int num : numbers) {
            System.out.println(num); // 不会出现索引越界
        }
      
        // 3. 使用System.arraycopy进行高效数组拷贝
        int[] source = {1, 2, 3, 4, 5};
        int[] destination = new int[5];
        System.arraycopy(source, 0, destination, 0, source.length);
      
        // 4. 对于对象数组,注意深浅拷贝的区别
        Person[] persons = {new Person("Alice"), new Person("Bob")};
        Person[] shallowCopy = persons; // 浅拷贝
        Person[] deepCopy = Arrays.copyOf(persons, persons.length); // 深拷贝(但对象本身还是共享的)
    }
}

class Person {
    String name;
    public Person(String name) {
        this.name = name;
    }
}

7. 数组与集合的转换

import java.util.*;

public class ArrayCollectionConversion {
    public static void main(String[] args) {
        // 数组转List
        String[] array = {"Java", "Python", "C++"};
        List<String> list = Arrays.asList(array);
        System.out.println("List: " + list);
      
        // List转数组
        List<Integer> numberList = new ArrayList<>();
        numberList.add(1);
        numberList.add(2);
        numberList.add(3);
      
        Integer[] numberArray = numberList.toArray(new Integer[0]);
        System.out.println("Array: " + Arrays.toString(numberArray));
      
        // 使用Stream API
        int[] primitiveArray = {1, 2, 3, 4, 5};
        List<Integer> streamList = Arrays.stream(primitiveArray)
                                        .boxed()
                                        .collect(Collectors.toList());
        System.out.println("Stream转换: " + streamList);
    }
}

总结

Java数组是基础且重要的数据结构,掌握其特性和常用方法对于Java编程至关重要。记住数组的固定大小特性,合理使用Arrays工具类,注意数组拷贝的深浅问题,这些都是编写高质量Java代码的关键。


评论