第20章

Java数组操作

掌握数组复制、排序和搜索的高级操作技巧

学习目标

Java数组操作详解

在Java编程中,数组是最基础也是最重要的数据结构之一。掌握数组的高级操作技巧,包括复制、排序和搜索,对于编写高效的程序至关重要。本章将深入探讨这些操作的实现方法和最佳实践。

数组复制

复制方法示例:
// 使用Arrays.copyOf()
int[] copy = Arrays.copyOf(original, original.length);

// 使用System.arraycopy()
System.arraycopy(src, 0, dest, 0, length);
  • for循环复制 - 最基础的方法
  • System.arraycopy() - 高性能原生方法
  • Arrays.copyOf() - 简洁易用
  • clone() - 最简单的完整复制

数组排序

排序方法示例:
// 内置排序
Arrays.sort(array);

// 冒泡排序
for (int i = 0; i < n-1; i++) {
    for (int j = 0; j < n-i-1; j++) {
        if (array[j] > array[j+1]) {
            // 交换元素
        }
    }
}
  • Arrays.sort() - 内置高效排序
  • 冒泡排序 - 简单易理解
  • 选择排序 - 交换次数少
  • 快速排序 - 平均性能最佳

数组搜索

搜索方法示例:
// 线性搜索
for (int i = 0; i < array.length; i++) {
    if (array[i] == target) return i;
}

// 二分搜索
int index = Arrays.binarySearch(sortedArray, target);
  • 线性搜索 - 适用于未排序数组
  • 二分搜索 - 高效搜索已排序数组
  • Arrays.binarySearch() - 内置二分搜索
  • 查找最值 - 特殊的搜索操作

算法性能对比

不同的数组操作方法在性能上存在显著差异,选择合适的算法对程序性能至关重要。

数组复制方法对比

方法 语法 性能 适用场景
for循环 for(int i=0; i<len; i++) 较慢 学习和简单场景
System.arraycopy() System.arraycopy(src,0,dest,0,len) 最快 大数组复制
Arrays.copyOf() Arrays.copyOf(array, length) 常规复制需求
clone() array.clone() 完整复制

排序算法对比

算法 时间复杂度 空间复杂度 稳定性 适用场景
冒泡排序 O(n²) O(1) 稳定 小数组,教学
选择排序 O(n²) O(1) 不稳定 小数组
快速排序 O(n log n) O(log n) 不稳定 大数组,一般情况
Arrays.sort() O(n log n) O(log n) 稳定 生产环境推荐

搜索算法对比

算法 时间复杂度 前提条件 适用场景
线性搜索 O(n) 未排序数组
二分搜索 O(log n) 数组已排序 已排序数组
Arrays.binarySearch() O(log n) 数组已排序 生产环境推荐

完整代码示例

ArrayCopyExample.java - 数组复制操作示例
public class ArrayCopyExample {
    public static void main(String[] args) {
        System.out.println("=== Java数组复制操作示例 ===");
        
        int[] originalArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        System.out.println("原始数组:");
        printArray(originalArray);
        
        System.out.println("\n1. 使用for循环复制:");
        int[] copyByLoop = copyArrayByLoop(originalArray);
        printArray(copyByLoop);
        
        System.out.println("\n2. 使用System.arraycopy()复制:");
        int[] copyBySystem = copyArrayBySystem(originalArray);
        printArray(copyBySystem);
        
        System.out.println("\n3. 使用Arrays.copyOf()复制:");
        int[] copyByArrays = java.util.Arrays.copyOf(originalArray, originalArray.length);
        printArray(copyByArrays);
        
        System.out.println("\n4. 使用clone()方法复制:");
        int[] copyByClone = originalArray.clone();
        printArray(copyByClone);
    }
    
    public static int[] copyArrayByLoop(int[] source) {
        int[] copy = new int[source.length];
        for (int i = 0; i < source.length; i++) {
            copy[i] = source[i];
        }
        return copy;
    }
    
    public static int[] copyArrayBySystem(int[] source) {
        int[] copy = new int[source.length];
        System.arraycopy(source, 0, copy, 0, source.length);
        return copy;
    }
    
    public static void printArray(int[] array) {
        System.out.print("[");
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]);
            if (i < array.length - 1) {
                System.out.print(", ");
            }
        }
        System.out.println("]");
    }
}
💻 查看完整代码 - 在线IDE体验

数组操作最佳实践

性能优化建议

推荐做法

// 推荐:使用System.arraycopy()处理大数组
System.arraycopy(src, 0, dest, 0, length);

// 推荐:使用Arrays.copyOf()处理常规需求
int[] copy = Arrays.copyOf(original, newLength);

// 推荐:生产环境使用内置排序
Arrays.sort(array);

// 推荐:已排序数组使用二分搜索
int index = Arrays.binarySearch(sortedArray, target);
  • 大数组复制使用System.arraycopy()
  • 生产环境优先使用内置方法
  • 频繁搜索时先排序再使用二分搜索
  • 根据数据规模选择合适算法

避免做法

// 避免:大数组使用for循环复制
for (int i = 0; i < largeArray.length; i++) {
    copy[i] = largeArray[i];
}

// 避免:大数组使用O(n²)排序算法
// 冒泡排序、选择排序等

// 避免:已排序数组使用线性搜索
for (int i = 0; i < sortedArray.length; i++) {
    if (sortedArray[i] == target) return i;
}
  • 大数组避免使用低效的复制方法
  • 避免在大数据集上使用O(n²)算法
  • 已排序数组不要使用线性搜索
  • 不要忽视算法的时间复杂度

实际应用场景

数组操作的实际应用

  • 学生成绩管理:复制备份数据、排序计算排名、搜索特定学生
  • 销售数据分析:处理销售数据、排序找出趋势、搜索异常数据
  • 游戏排行榜:排序玩家分数、快速查找玩家排名
  • 库存管理系统:排序商品、搜索特定商品、复制历史数据
  • 日志分析:排序日志条目、搜索错误信息、备份重要数据

性能注意事项

  • 大数据集操作时要特别注意算法的时间复杂度
  • 频繁的数组操作可能导致内存碎片,考虑使用集合类
  • 多线程环境下要注意数组操作的线程安全性
  • 对于超大数组,考虑分批处理或使用流式处理

本章小结