Java 数组专项知识点

一、数组基础与声明

1.1 数组基本概念


// 数组是相同类型数据的固定大小的顺序集合
public class ArrayBasics {
    // 声明方式
    int[] arr1;        // 推荐
    int arr2[];        // C风格,不推荐
    
    // 初始化方式
    int[] numbers = new int[5];           // 动态初始化
    int[] scores = {90, 85, 88, 92, 78};  // 静态初始化
    int[] values = new int[]{1, 2, 3};    // 完整语法
    
    // 默认值
    int[] intArr = new int[3];     // 默认: [0, 0, 0]
    boolean[] boolArr = new boolean[2]; // 默认: [false, false]
    String[] strArr = new String[2];    // 默认: [null, null]
}
 

1.2 数组属性与方法


public class ArrayProperties {
    public static void main(String[] args) {
        int[] arr = {10, 20, 30, 40, 50};
        
        // 1. 数组长度(不可变)
        System.out.println("长度: " + arr.length);  // 5
        
        // 2. 数组是对象
        System.out.println(arr.getClass());         // class [I
        System.out.println(arr instanceof Object);  // true
        
        // 3. 数组元素的访问
        arr[0] = 100;      // 修改第一个元素
        int value = arr[2]; // 访问第三个元素
        
        // 4. 数组越界异常
        try {
            arr[10] = 100;  // ArrayIndexOutOfBoundsException
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界!");
        }
    }
}
 

二、数组操作与遍历

2.1 遍历方法


public class ArrayTraversal {
    public static void main(String[] args) {
        int[] nums = {1, 2, 3, 4, 5};
        
        // 1. 传统for循环(可控制索引)
        for (int i = 0; i < nums.length; i++) {
            System.out.println("索引 " + i + ": " + nums[i]);
        }
        
        // 2. 增强for循环(只读,简洁)
        for (int num : nums) {
            System.out.println(num);
        }
        
        // 3. while循环
        int index = 0;
        while (index < nums.length) {
            System.out.println(nums[index++]);
        }
        
        // 4. 使用Stream API(Java 8+)
        Arrays.stream(nums).forEach(System.out::println);
    }
}
 

2.2 数组复制


public class ArrayCopy {
    public static void main(String[] args) {
        int[] source = {1, 2, 3, 4, 5};
        
        // 1. System.arraycopy() - 高性能
        int[] dest1 = new int[5];
        System.arraycopy(source, 0, dest1, 0, source.length);
        
        // 2. Arrays.copyOf() - 简洁
        int[] dest2 = Arrays.copyOf(source, source.length);
        int[] dest3 = Arrays.copyOf(source, 10);  // 扩容,多余位置补0
        
        // 3. Arrays.copyOfRange() - 复制范围
        int[] dest4 = Arrays.copyOfRange(source, 1, 4); // [2, 3, 4]
        
        // 4. clone()方法
        int[] dest5 = source.clone();
        
        // 5. 手动复制
        int[] dest6 = new int[source.length];
        for (int i = 0; i < source.length; i++) {
            dest6[i] = source[i];
        }
        
        // 注意:浅拷贝 vs 深拷贝(对于对象数组)
        Person[] persons = {new Person("Alice"), new Person("Bob")};
        Person[] shallowCopy = persons.clone();  // 浅拷贝
        shallowCopy[0].setName("Charlie");       // 影响原数组
    }
}
 

三、多维数组

3.1 二维数组


public class TwoDimensionalArray {
    public static void main(String[] args) {
        // 1. 声明与初始化
        int[][] matrix1 = new int[3][4];          // 3行4列
        int[][] matrix2 = {{1,2,3}, {4,5,6}, {7,8,9}};
        
        // 2. 不规则数组
        int[][] irregular = new int[3][];
        irregular[0] = new int[2];
        irregular[1] = new int[3];
        irregular[2] = new int[1];
        
        // 3. 遍历二维数组
        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();
        }
        
        // 4. 增强for循环遍历
        for (int[] row : matrix2) {
            for (int num : row) {
                System.out.print(num + " ");
            }
            System.out.println();
        }
    }
}
 

3.2 三维及以上数组


public class MultiDimensionalArray {
    public static void main(String[] args) {
        // 三维数组(立方体)
        int[][][] cube = new int[3][4][5];
        
        // 初始化
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                for (int k = 0; k < 5; k++) {
                    cube[i][j][k] = i + j + k;
                }
            }
        }
        
        // 不规则多维数组
        int[][][] irregular3D = new int[2][][];
        irregular3D[0] = new int[3][];
        irregular3D[0][0] = new int[2];
        irregular3D[0][1] = new int[1];
        irregular3D[0][2] = new int[4];
    }
}
 

四、数组与算法

4.1 排序算法实现


public class ArraySorting {
    // 1. 冒泡排序
    public static void bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 交换
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
    
    // 2. 选择排序
    public static void selectionSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            // 交换
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }
    
    // 3. 快速排序
    public static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            int pivotIndex = partition(arr, low, high);
            quickSort(arr, low, pivotIndex - 1);
            quickSort(arr, pivotIndex + 1, high);
        }
    }
    
    private static int partition(int[] arr, int low, int high) {
        int pivot = arr[high];
        int i = low - 1;
        for (int j = low; j < high; j++) {
            if (arr[j] < pivot) {
                i++;
                swap(arr, i, j);
            }
        }
        swap(arr, i + 1, high);
        return i + 1;
    }
    
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
 

4.2 查找算法


public class ArraySearch {
    // 1. 线性查找
    public static int linearSearch(int[] arr, int target) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == target) {
                return i;
            }
        }
        return -1;
    }
    
    // 2. 二分查找(要求数组有序)
    public static int binarySearch(int[] arr, int target) {
        int left = 0;
        int right = arr.length - 1;
        
        while (left <= right) {
            int mid = left + (right - left) / 2;
            
            if (arr[mid] == target) {
                return mid;
            } else if (arr[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return -1;
    }
}
 

4.3 常见数组算法


public class ArrayAlgorithms {
    // 1. 求最大值/最小值
    public static int findMax(int[] arr) {
        if (arr.length == 0) throw new IllegalArgumentException("数组为空");
        int max = arr[0];
        for (int num : arr) {
            if (num > max) max = num;
        }
        return max;
    }
    
    // 2. 求平均值
    public static double average(int[] arr) {
        if (arr.length == 0) return 0;
        int sum = 0;
        for (int num : arr) sum += num;
        return (double) sum / arr.length;
    }
    
    // 3. 数组反转
    public static void reverse(int[] arr) {
        int left = 0;
        int right = arr.length - 1;
        while (left < right) {
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
    
    // 4. 删除指定元素
    public static int[] removeElement(int[] arr, int target) {
        int count = 0;
        // 统计非目标元素个数
        for (int num : arr) {
            if (num != target) count++;
        }
        
        // 创建新数组
        int[] result = new int[count];
        int index = 0;
        for (int num : arr) {
            if (num != target) {
                result[index++] = num;
            }
        }
        return result;
    }
}
 

五、Arrays 工具类

5.1 常用方法


import java.util.Arrays;
import java.util.Comparator;

public class ArraysUtils {
    public static void main(String[] args) {
        int[] arr = {5, 3, 8, 1, 9};
        
        // 1. 排序
        Arrays.sort(arr);  // 升序排序
        System.out.println(Arrays.toString(arr)); // [1, 3, 5, 8, 9]
        
        // 2. 并行排序(大数据量性能更好)
        int[] largeArr = new int[1000000];
        Arrays.parallelSort(largeArr);
        
        // 3. 二分查找
        int index = Arrays.binarySearch(arr, 5);  // 返回索引2
        
        // 4. 填充数组
        int[] filled = new int[5];
        Arrays.fill(filled, 7);  // [7, 7, 7, 7, 7]
        
        // 5. 数组比较
        int[] arr1 = {1, 2, 3};
        int[] arr2 = {1, 2, 3};
        boolean equal = Arrays.equals(arr1, arr2);  // true
        
        // 6. 数组转字符串
        String str = Arrays.toString(arr);
        
        // 7. 数组转列表
        Integer[] boxedArr = {1, 2, 3};
        List<Integer> list = Arrays.asList(boxedArr);
        
        // 8. 流操作
        int sum = Arrays.stream(arr).sum();
        OptionalInt max = Arrays.stream(arr).max();
        
        // 9. 多维数组处理
        int[][] matrix = {{1,2}, {3,4}};
        String deepStr = Arrays.deepToString(matrix);
        boolean deepEqual = Arrays.deepEquals(matrix, new int[][]{{1,2},{3,4}});
        
        // 10. 自定义排序
        Integer[] numbers = {5, 2, 8, 1};
        Arrays.sort(numbers, Comparator.reverseOrder());  // 降序排序
    }
}
 

六、数组与集合转换

6.1 数组与List互转


import java.util.*;

public class ArrayCollectionConversion {
    public static void main(String[] args) {
        // 1. 数组转List
        String[] array = {"A", "B", "C"};
        
        // 方法1: Arrays.asList() - 返回固定大小列表
        List<String> list1 = Arrays.asList(array);
        // list1.add("D"); // 抛出UnsupportedOperationException
        
        // 方法2: new ArrayList<>(Arrays.asList())
        List<String> list2 = new ArrayList<>(Arrays.asList(array));
        list2.add("D");  // 正常
        
        // 方法3: Collections.addAll()
        List<String> list3 = new ArrayList<>();
        Collections.addAll(list3, array);
        
        // 2. List转数组
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        
        // 方法1: toArray() - 返回Object[]
        Object[] objArray = list.toArray();
        
        // 方法2: toArray(T[]) - 推荐
        String[] strArray = list.toArray(new String[0]);
        String[] strArray2 = list.toArray(new String[list.size()]);
        
        // 3. Set转数组
        Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 3));
        Integer[] setArray = set.toArray(new Integer[0]);
    }
}
 

七、数组内存模型

7.1 内存分配


public class ArrayMemory {
    // 数组在内存中的存储
    public static void memoryDemo() {
        // 栈内存存储引用,堆内存存储数组元素
        int[] arr = new int[3];  // arr引用在栈中,数组对象在堆中
        
        // 多维数组的内存结构
        int[][] matrix = new int[2][3];
        // matrix引用在栈中,外层数组在堆中,内层数组也在堆中
    }
    
    // 数组的内存对齐与缓存友好性
    public static void cacheFriendlyDemo() {
        // 连续内存访问(缓存友好)
        int[][] rowMajor = new int[1000][1000];
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            for (int j = 0; j < 1000; j++) {
                rowMajor[i][j] = i + j;  // 行优先访问
            }
        }
        
        // 不连续内存访问(缓存不友好)
        int[][] colMajor = new int[1000][1000];
        for (int j = 0; j < 1000; j++) {
            for (int i = 0; i < 1000; i++) {
                colMajor[i][j] = i + j;  // 列优先访问
            }
        }
    }
}
 

八、数组高级特性

8.1 动态数组模拟


public class DynamicArray<E> {
    private Object[] data;
    private int size;
    private static final int DEFAULT_CAPACITY = 10;
    
    public DynamicArray() {
        data = new Object[DEFAULT_CAPACITY];
        size = 0;
    }
    
    // 添加元素
    public void add(E element) {
        ensureCapacity(size + 1);
        data[size++] = element;
    }
    
    // 获取元素
    @SuppressWarnings("unchecked")
    public E get(int index) {
        checkIndex(index);
        return (E) data[index];
    }
    
    // 扩容
    private void ensureCapacity(int minCapacity) {
        if (minCapacity > data.length) {
            int newCapacity = Math.max(data.length * 2, minCapacity);
            data = Arrays.copyOf(data, newCapacity);
        }
    }
    
    private void checkIndex(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
    }
    
    public int size() {
        return size;
    }
}
 

8.2 数组与泛型


public class ArrayGenerics {
    // 不能创建泛型数组
    // T[] arr = new T[10];  // 编译错误
    
    // 解决方法1:使用Object数组,然后强制转换
    @SuppressWarnings("unchecked")
    public static <T> T[] createGenericArray(Class<T> clazz, int size) {
        return (T[]) java.lang.reflect.Array.newInstance(clazz, size);
    }
    
    // 解决方法2:使用列表代替
    public static <T> List<T> createGenericList(Class<T> clazz, int size) {
        return new ArrayList<>(size);
    }
    
    // 泛型方法处理数组
    public static <T> void swap(T[] array, int i, int j) {
        T temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}
 

九、性能优化

9.1 数组性能技巧


public class ArrayPerformance {
    // 1. 预分配大小
    public static void preAllocate() {
        // 不好:频繁扩容
        ArrayList<Integer> list = new ArrayList<>();
        
        // 好:预分配容量
        int expectedSize = 10000;
        ArrayList<Integer> optimizedList = new ArrayList<>(expectedSize);
    }
    
    // 2. 使用基本类型数组
    public static void primitiveVsBoxed() {
        // 不好:使用包装类型数组(内存占用大)
        Integer[] boxedArray = new Integer[1000000];
        
        // 好:使用基本类型数组
        int[] primitiveArray = new int[1000000];
    }
    
    // 3. 批量复制 vs 单元素复制
    public static void batchCopy() {
        int[] source = new int[1000];
        int[] dest = new int[1000];
        
        // 不好:单元素复制
        for (int i = 0; i < source.length; i++) {
            dest[i] = source[i];
        }
        
        // 好:批量复制
        System.arraycopy(source, 0, dest, 0, source.length);
    }
    
    // 4. 缓存数组长度
    public static void cacheLength() {
        int[] arr = new int[1000];
        
        // 不好:每次循环都调用length
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i;
        }
        
        // 好:缓存数组长度
        int len = arr.length;
        for (int i = 0; i < len; i++) {
            arr[i] = i;
        }
    }
}
 

十、常见应用场景

10.1 数组在实际中的应用


public class ArrayApplications {
    // 1. 存储配置项
    private static final String[] WEEKDAYS = 
        {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
    
    // 2. 缓存最近访问记录
    class LRUCache<K, V> {
        private Entry<K, V>[] table;
        private int capacity;
        
        // 实现LRU缓存...
    }
    
    // 3. 矩阵运算
    public static double[][] matrixMultiply(double[][] A, double[][] B) {
        int rowsA = A.length;
        int colsA = A[0].length;
        int colsB = B[0].length;
        
        double[][] result = new double[rowsA][colsB];
        
        for (int i = 0; i < rowsA; i++) {
            for (int j = 0; j < colsB; j++) {
                for (int k = 0; k < colsA; k++) {
                    result[i][j] += A[i][k] * B[k][j];
                }
            }
        }
        return result;
    }
    
    // 4. 游戏开发中的网格
    class GameBoard {
        private char[][] board;
        
        public GameBoard(int rows, int cols) {
            board = new char[rows][cols];
            initializeBoard();
        }
        
        private void initializeBoard() {
            for (char[] row : board) {
                Arrays.fill(row, '-');
            }
        }
    }
}
 

十一、最佳实践与注意事项

11.1 最佳实践


public class ArrayBestPractices {
    // 1. 防御性编程
    public static int sumArray(int[] arr) {
        if (arr == null) {
            throw new IllegalArgumentException("数组不能为null");
        }
        
        int sum = 0;
        for (int num : arr) {
            sum += num;
        }
        return sum;
    }
    
    // 2. 使用增强for循环避免越界
    public static void safeIteration(int[] arr) {
        // 安全:不会越界
        for (int num : arr) {
            System.out.println(num);
        }
    }
    
    // 3. 返回空数组而非null
    public static int[] getNumbers() {
        // 不好:返回null
        // return null;
        
        // 好:返回空数组
        return new int[0];
    }
    
    // 4. 使用System.arraycopy进行数组复制
    public static int[] copyArray(int[] original) {
        int[] copy = new int[original.length];
        System.arraycopy(original, 0, copy, 0, original.length);
        return copy;
    }
}
 

11.2 常见陷阱


public class ArrayPitfalls {
    public static void main(String[] args) {
        // 陷阱1:数组越界
        int[] arr = new int[5];
        // arr[5] = 10;  // ArrayIndexOutOfBoundsException
        
        // 陷阱2:空指针异常
        int[] nullArr = null;
        // System.out.println(nullArr.length);  // NullPointerException
        
        // 陷阱3:浅拷贝
        Person[] persons = {new Person("Alice")};
        Person[] shallowCopy = persons.clone();
        shallowCopy[0].setName("Bob");  // 原数组也被修改
        
        // 陷阱4:数组协变性
        Object[] objArray = new String[10];
        objArray[0] = "Hello";  // OK
        // objArray[1] = new Integer(10);  // ArrayStoreException
        
        // 陷阱5:数组大小固定
        int[] fixed = new int[5];
        // fixed.add(6);  // 没有add方法,大小固定
        
        // 陷阱6:多维数组的length
        int[][] matrix = new int[3][4];
        System.out.println(matrix.length);     // 3(行数)
        System.out.println(matrix[0].length);  // 4(列数)
    }
}
 

总结

关键知识点

1. 数组特点:固定大小、类型相同、连续内存、下标访问
2. 内存模型:引用在栈,数据在堆
3. 操作方式:遍历、复制、排序、查找
4. 工具类:Arrays提供丰富工具方法
5. 性能考虑:预分配、批量操作、缓存友好访问模式

选择建议

· 大小固定且类型一致 → 使用数组
· 需要动态调整大小 → 使用ArrayList
· 需要键值对 → 使用Map
· 需要去重或无序 → 使用Set

性能调优

1. 对于大量数据,使用基本类型数组而非包装类型
2. 批量操作使用System.arraycopy
3. 多维数组按行优先顺序访问
4. 合理预分配数组大小

数组是Java中最基础的数据结构,理解其特性和原理对编写高效代码至关重要。在实际开发中,根据需求选择合适的数组或集合类,并注意避免常见的陷阱。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐