Java数组操作详解:引用、排序、查找与对象数组应用

云舒
云舒
发布时间:2026-10-16| 4人浏览过
原创

深入解析Java数组的底层逻辑与常用操作,包括数据类型的初始化、方法参数中的引用传递陷阱、内置类库的使用,以及冒泡排序、二分查找等经典算法的实现,最后通过对象数组案例展示复杂数据的存储与管理。

1. 数组的基础概念与内存模型

数组是Java中用于存储同一种数据类型元素的容器。由于基本数据类型(如 int)占用栈空间较小,而引用类型占据堆空间较大,理解数组的内存分布是掌握其操作的关键。

第1步:数组的动态初始化

目的是为数组分配固定长度的内存空间,随后逐个赋值。

  1. 定义变量:声明一个整型数组引用。
    int data[] = null;
  2. 分配内存:创建具体大小的数组实例。
    data = new int [3];
  3. 元素赋值:通过下标访问特定内存位置并修改内容。
    data[0] = 10; data[1] = 20; data[2] = 30;

第2步:理解数组的引用传递

当多个引用指向同一个数组对象时,它们是引用传递而非值传递。对其中一个引用的修改会直接影响原数组,这在内存图中表现为不同的栈变量指向同一块堆内存区域。

  1. 建立关联:将 temp 引用指向 data 所在的数组对象。
    temp = data;
  2. 执行修改:通过新引用修改第一个元素,原数组同步变更。
    temp[0] = 99;
  3. 验证结果:遍历数组,观察输出是否反映最新状态。
    for(int i=0 ;i < temp.length ; i++) { System.out.println(temp[i]); }

第3步:数组的静态初始化

在定义数组的同时直接指定初始值,简化了代码结构。Java支持两种语法格式,编译器均能自动识别长度:

  • 简化格式:int data [] = {1,2,3};
  • 完整格式:int data [] = new int []{1,2,3};

注意:数组一旦创建,其在内存中的物理长度即固定不变,无法直接“扩容”,这是数组相比 ArrayList 等集合类的一个显著限制。

2. 数组的方法交互与内置工具

在实际开发中,通常会将数组的操作封装成独立方法,以便复用和测试。需要特别注意参数传递过程中的“浅复制”现象。

第4步:方法接收与返回数组

方法可以将整个数组作为参数传入,也可以返回一个新的数组引用给调用者。

返回数组示例:编写一个初始化方法,返回填充好的整数数组供主函数处理。
public static int[] init() { return new int []{1,2,3,4,5}; }

操作数组示例:传入数组并在方法内部修改其属性,外部变量将同步看到变化。

public class TestDemo2{
    public static void main(String args[]){
        int data [] = init();		//接受数组
        inc(data);		//扩大数组的内容
        printfArray(data);	//int temp [] = data;
    }
    
    //该方法没有返回值,但直接修改了arr引用的内存数据
    public static void inc(int arr[]){	
        for(int i = 0 ; i<arr.length ; i++){
            arr[i] *= 2;
        }
    }
    
    public static int[] init(){
        return new int []{1,2,3,4,5};
    }
    
    //打印数组通用方法
    public static void printfArray(int temp[]){
        for(int i = 0; i < temp.length; i++){
            System.out.println(temp[i] + "、");
        }
    }
}

第5步:使用 Java 类库辅助操作

标准库提供了高效的工具类 java.util.Arrays,可避免重复造轮子。

  1. 一键排序:直接使用 sort() 方法对数组进行升序排列。
    java.util.Arrays.sort(data);
  2. 数据拷贝:利用 System.arraycopy() 将部分元素从一个数组映射到另一个数组的不同位置。
    System.arraycopy(源数组名称,源数组开始索引,目标数组名称,目标数组开始索引,拷贝长度);

3. 数组的经典算法实战

掌握数组的底层操作是学习数据结构的第一步,以下介绍了数据分析、排序优化及高效检索的实现逻辑。

第6步:基础数据统计分析

通过单次循环即可完成最值查找、总和计算与平均值求取,提升数据处理效率。

public class TestDemo3{
    public static void main(String args[]){
        int data [] = new int [] {12,3,54,23,64,11};
        int max = data[0];	
        int min = data[0];
        int sum = 0;
        
        for(int i = 0; i < data.length ; i++){
            sum += data[i]; 
            if(data[i]>max) {
                max = data[i];
            }
            if(data[i]<min){
                min = data[i];
            }
        }
        
        System.out.println("max = " + max);		
        System.out.println("min = " + min);		
        System.out.println("sum = " + sum);		
        System.out.println("average = " + sum/(double)data.length);	//求平均值
    }
}

第7步:实现冒泡排序算法

冒泡排序通过重复遍历数组,交换相邻的元素来实现排序。其时间复杂度较高,属于 $O(N^2)$ 级别。

  1. 外层循环:控制需要进行对比的总轮数。
  2. 内层循环:在每一轮中,依次比较相邻两个元素,若顺序错误则互换。
public class TestDemo4{
    public static void main(String args[]){
        int data [] = new int [] {9,8,5,6,4,2,1,0,3,7};
        sort(data);
        printfArray(data);
    }
    
    public static void sort(int arr[]){//实现数组的升序排序
        for(int i = 0 ;i < arr.length - 1 ; i++){
            for(int j = 0 ; j < arr.length - i - 1; j++){
                if(arr[j]>arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }
    
    public static void printfArray(int temp[]){
        for(int i = 0; i < temp.length; i++){
            System.out.println(temp[i] + "、");
        }
    }
}

第8步:数组的逆序转置

一维数组转置采用双指针策略(头尾向中间逼近),二维矩阵转置则是行列坐标互换。

public class TestDemo4{
    public static void main(String args[]){
        int data [] = new int [] {9,8,7,6,5,4,3,2,1,0};
        reverse(data);
        printfArray(data);
    }
    
    public static void reverse(int arr[]){
        int head = 0;	//头部索引
        int tail = arr.length - 1;	//尾部索引
        //只要头部索引小于尾部索引就继续交换
        while(head < tail){
            int temp = arr[head];
            arr[head] = arr[tail];
            arr[tail] = temp;
            head ++;
            tail --;
        }
    }
}

对于二维数组的对角线转置,需遍历非对角线一侧的元素,并与关于主对角线对称的元素进行交换。

public class TestDemo5{
    public static void main(String args[]){
        int data [][] = new int [][] {{9,8,7},{6,5,4},{3,2,1}};
        reverse(data);
        printfArray(data);
    }
    
    public static void reverse(int arr[][]){
        for(int i = 0 ; i < arr.length ; i++){
            for(int j = i; j < arr.length; j++){
                if(i != j){
                    int temp = arr[i][j];
                    arr[i][j] = arr[j][i];
                    arr[j][i] = temp; 
                } 
            }
        }
    }
}

第9步:二分查找法优化

相比于线性查找 $O(N)$ 的时间复杂度,二分查找法要求输入数组必须是已排序的。它通过不断将查找区间缩小一半,将平均时间复杂度降至 $O( ext{log} N)$。

操作逻辑:

  1. 计算当前区间的中间索引 mid。
  2. 若中间值等于关键字,直接返回索引。
  3. 若关键字大于中间值,则在右半区间继续搜索。
  4. 若关键字小于中间值,则在左半区间继续搜索。
public class TestDemo6{
    public static void main(String args[]){
        int data [] = new int [] {1,2,3,4,5,6,7,8,9,10};
        int search = 9;
        System.out.println(binarySearch(data, 0 , data.length-1, search));
    }
    
    public static int binarySearch(int arr[],int from, int to, int key){
        if(from <= to){
            int mid = (from + to) / 2;	//更稳健的中间位置索引计算
            if(arr[mid] == key){
                return mid;
            }else if(key > arr[mid]){
                return binarySearch(arr, mid+1 , to , key);
            }else{
                return binarySearch(arr, from, mid-1, key);
            }
        }
        return -1; // 未找到
    }
}

4. 高级应用:对象数组管理

除了基本数据类型,数组可以存储类的实例,这被称为对象数组。它适合用来批量管理具有相同属性的实体对象。

第10步:创建与遍历对象数组

无论是动态还是静态初始化,核心步骤是先声明引用数组,再为每个引用单独实例化具体对象。

class Person{
    private String name;
    private int age;
    public Person(String n, int a){
        name = n;
        age = a;
    }
    public String getInfo(){
        return "name = " + name + ",age = " + age;
    }
}

public class TestDemo7{
    public static void main(String args[]){
        // 1. 动态初始化:先建空容器
        Person per [] = new Person [3];		
        per[0] = new Person("张三",22);
        per[1] = new Person("李四",30);
        per[2] = new Person("王五",13);

        // 2. 静态初始化:定义时即完成装箱
        Person per1 [] = new Person [] {
            new Person("张三1",22),
            new Person("张三2",22)
        }; 		
        
        // 3. 统一遍历获取信息
        for(int i = 0;i < per.length ; i++){
            System.out.println(per[i].getInfo());
        }
        System.out.println();
        for(int i = 0;i < per.length-1 ; i++){
            System.out.println(per1[i].getInfo());
        }
    }
}

以上就是Java数组的详细操作流程与应用实践的全部内容。文章涵盖了从基础语法的正确写法到冒泡排序与二分查找算法的逻辑拆解,并演示了如何通过对象数组处理复杂的业务数据结构,更多关于Java进阶的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。