1个月征服Java:零基础直达企业级开发——Java数组

目录

引言

 一、认识数组

1. 什么数组

2. 数组的应用场景

二、数组的定义和访问

2.1 数组的静态初始化

2.2 数组的元素访问

2.3 数组的遍历

2.4 数组静态初始化案例

2.5 数组的动态初始化

2.6 数组动态初始化案例

三、数组在计算机中的执行原理

3.1 数组的执行原理,Java程序的执行原理

3.2 多个变量指向同一个数组的问题

四、数组专项练习

4.1 数组求最值

4.2 数组元素反转

4.3 随机排名

五、Debug调试工具


引言

在Java的世界里,​​数组是数据组织的基石​​,更是迈向企业级开发的必经之路。无论是处理海量用户数据、优化算法性能,还是构建复杂业务逻辑,数组都扮演着不可替代的角色。它用最简洁的容器思维,将零散的数据转化为结构化力量,让程序拥有处理批量信息的能力。

​为什么数组如此关键?​
试想:当你的程序需要管理成百上千条订单、实时分析用户行为、或快速排序搜索结果时,变量(Variable)的单一存储模式将瞬间崩溃。而​​数组(Array)​​ 正是为解决这类问题而生——它通过​​连续的内存空间​​和​​高效的索引机制​​,让批量数据的存储、遍历与计算变得轻而易举。

​本博客将带您从零开始,以企业级应用为目标,系统攻克Java数组的核心技能:​

  1. ​认知跃迁​​:从基础概念到内存原理,揭示数组的底层逻辑,理解int[] arr背后的计算机科学本质;
  2. ​实战进阶​​:通过静态/动态初始化、元素访问、遍历技巧,亲手构建销售额统计、评委打分系统等企业级案例;
  3. ​原理深挖​​:剖析栈(Stack)与堆(Heap)中数组的执行机制,破解多个变量指向同一数组的“共享陷阱”;
  4. ​能力淬炼​​:专项训练数组求最值、反转、随机排序等高频题型,培养算法思维与调试能力(Debug)。

无论你是初探编程的开发者,还是渴望夯实基础的进阶者,本篇内容将以​​场景化代码 + 可视化内存图解 + 企业级案例​​,助你一个月内彻底掌握数组精髓,让批量数据处理从瓶颈变为优势!

 一、认识数组

先来认识一下什么数组

1. 什么数组

数组就是一个容器,用来存一批同种类型的数据的。

比如:想要存储 20,10,80,60,90 这些数据。 我们可以把代码写成这样

int[] array = {20,10,80,60,90};

比如:想要存储 “牛二“,“西门“,“全蛋“ 这些数据。我们可以把代码写成这样

String[] names = {"牛二", "西门", "全蛋"};

2. 数组的应用场景

有变量,为什么还要有数组呢? 比如,我们要做一个点名器

如果用变量来做的话,代码是这样子的

如果用数组来做的话,代码是这样子的

一对比我们发现数组的写法比变量的写法更加简洁,所以我们可以得出一个结论

结论:遇到批量数据的存储和操作时,数组比变量更适合

二、数组的定义和访问

各位同学,我们已经知道数组是用来干什么的。那么如何使用Java语言写一个数组呢?这里就需要学习一下数组的初始化格式。

数组有两种初始化的方式,一种是静态初始化、一种是动态初始化。我们先用静态初始化来学习数组的操作。

2.1 数组的静态初始化

所谓静态初始化指的是:在定义数组时直接给数组中的数据赋值。

1. 静态初始化标准格式:

数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3};

按照格式定义int类型、double类型数组

//定义数组,用来存储多个年龄
int[] ages = new int[]{12, 24, 36}
//定义数组,用来存储多个成绩
double[] scores = new double[]{89.9, 99.5, 59.5, 88.0};

2. 静态初始化简化格式

Java语言的设计者为了简化定义数组的写法,还为静态初始化提供了一种简化写法

数据类型[] 变量名 = {元素1,元素2,元素3};

使用简化格式定义int类型、double类型数组

//定义数组,用来存储多个年龄
int[] ages = {12, 24, 36}
//定义数组,用来存储多个成绩
double[] scores = {89.9, 99.5, 59.5, 88.0};

3. 注意哟!!

  • 定义数组时, 数据类型[] 数组名 也可写成 数据类型 数组名[]
//以下两种写法是等价的。但是建议大家用第一种,因为这种写法更加普遍
int[] ages = {12, 24, 36};
int ages[] = {12, 24, 36}

4. 数组在计算机中的基本原理

我们知道数组是怎么定义的之后,那么接下来看一下数组在计算机中的基本原理。

我们以int[] ages = {12,24,36};这句话为例,看一下这句话到底在计算机中做了那些事情。

  • 首先,左边int[] ages 表示定义了一个数组类型的变量,变量名叫ages
  • 其次,右边{12,24,36}表示创建一个数组对象,你完全可以把它理解成一个能装数据的东西。这个对象在内存中会有一个地址值[I@4c873330,每次创建一个数组对象都会有不用的地址值。
  • 然后,把右边的地址值[I@4c873330赋值给左边的ages变量
  • 所以,ages变量就可以通过地址值,找到数组这个东西。

2.2 数组的元素访问

各位同学,通过刚才的学习,我们知道数组是用来存储数据的。那么数组中存储的数据又如何访问呢?这里所说的访问,意思就是获取中数组中数据的值、或者给数组中的数据赋值。

这里先给大家统一几个概念,数组中存储的数据我们叫做元素;而且数组中的每一个元素都有一个编号与之对应,我们把这个编号叫做索引,这个索引是从0依次递增的整数。如下图所示

要想访问数组中的元素,格式如下

//数组名可以找到数组对象的地址,再通过索引就可以定位到具体的元素了
数组名[索引]

接下来用代码来演示一下

//索引:	   0   1   2
int[] arr = {12, 24, 36};
// 1、访问数组的全部数据
System.out.println(arr[0]); //12
System.out.println(arr[1]); //24
System.out.println(arr[2]); //36
//下面代码没有3索引,会出现ArrayIndexOutOfBoundsException 索引越界异常
//System.out.println(arr[3]); 

// 2、修改数组中的数据
arr[0] = 66;
arr[2] = 100;
System.out.println(arr[0]); //66
System.out.println(arr[1]); 0
System.out.println(arr[2]); //100

除了访问数组中的元素,我们可以获取数组中元素的个数,后面我们统称为数组的长度。

// 3、访问数组的元素个数:数组名.length
System.out.println(arr.length);

// 技巧:获取数组的最大索引: arr.length - 1(前提是数组中存在数据)
System.out.println(arr.length - 1);

int[] arr2 = {};
System.out.println(arr2.length - 1);

2.3 数组的遍历

各位同学,接下来我们学习一个对数组最最最常见的操作——数组遍历。所谓遍历意思就是将数组中的元素一个一个的取出来。

我们刚才学习了数组中元素的访问,访问元素必须用到索引,如下列代码。

int[] ages = {12, 24, 36};
System.out.println(ages[0]);
System.out.println(ages[1]);
System.out.println(ages[2]);

但是,如果数组中有很多很多元素,索引靠自己一个一个数肯定是不行的!我们可以使用for循环从0开始一直遍历到长度-1的位置,就可以获取所有的索引了。

当你获取到每一个索引,那么每一个元素不就获取到了吗?上代码吧

int[] ages = {12, 24, 36};
for (int i = 0; i < ages.length; i++) {
    // i的取值 = 0,1,2
    System.out.println(ages[i]); 
}

2.4 数组静态初始化案例

学习完数组的静态初始化之后,接下来我们做一个练习题来巩固一下。

需求:某部门5名员工的销售额分别是:16、26、36、6、100,请计算出他们部门的总销售额。

需求分析:
	1.看到有16、26、36、6、100这5个数据数据,而且数据值很明确;
		1)想到,可以使用数组静态初始化把这5个数据存起来
	
	2.请计算出他们部门的总销售额(这不就是求数组中数据的和吗?)
		2)必须先将数组中所有的元素遍历出来
		3)想要求和,得先有一个求和变量sum
		4)再将每一个元素和求和变量sum进行累加(求和思想)

按照分析的思路来写代码

// 1、定义一个数组存储5名员工的销售额
//索引          0   1    2  3   4
int[] money = {16, 26, 36, 6, 100};

// 3、定义一个变量用于累加求和
int sum = 0;

// 2、遍历这个数组中的每个数据。
for (int i = 0; i < money.length; i++) {
    // i = 0  1  2  3  4
    sum += money[i];
}
System.out.println("员工的销售总额:" + sum);

2.5 数组的动态初始化

各位同学,刚才我们初始化数组时,都是直接将元素写出来。但是还有另一个初始化数组的方式叫 动态初始化

动态初始化不需要我们写出具体的元素,而是指定元素类型和长度就行。格式如下

//数据类型[]  数组名 = new 数据类型[长度];
int[] arr = new int[3];

下面是动态初始化数组的原理图。我们发现int[] arr 其实就是一个变量,它记录了数组对象的地址值,而且数组中的元素默认值是0。

注意:

使用动态初始化定义数组时,根据元素类型不同,默认值也有所不同。

关于数组动态初始化的格式和原理,咱们就先学习到这里。

2.6 数组动态初始化案例

各位同学,接下来我们做一个数组动态初始化的案例。

案例需求:
	某歌唱比赛,需要开发一个系统:可以录入6名评委的打分,录入完毕后立即输出平均分做
	选手得分

需求分析:
	1.需要录入6名评委的分数,可以用一个数组来保存。
	   因为在评委没有录入分数之前,还不确定数组中应该存哪些数据。
	   所以可以使用数组的动态初始化
	2.遍历数组中的每一个位置,并录入分数,将分数存入数组中
	3.遍历数组中的每一个元素,对元素求和

代码如下

// 1、定义一个动态初始化的数组,负责后期存储6个评委的打分。
double[] scores = new double[6];

Scanner sc  = new Scanner(System.in);

// 2、遍历数组中的每个位置,录入评委的分数,存入到数组中去
for (int i = 0; i < scores.length; i++) {
    // i = 0 1 2 3 4 5
    System.out.println("请您输入当前第" + (i + 1) +"个评委的分数:");
    double score = sc.nextDouble();
    scores[i] = score;
}

// 3、遍历数组中的每个元素进行求和
double sum  = 0;
for (int i = 0; i < scores.length; i++) {
    sum += scores[i];
}
System.out.println("选手最终得分是:" + sum / scores.length);

三、数组在计算机中的执行原理

好的各位同学,在前面我们已经学习了数组的基本使用,也理解了数组的基本原理。由于数组是一个容器,变量也是一个容器,在理解他们执行原理的时候,有些同学就容易搞混,现在我把他们放在一起带着大家回顾一下他们的会执行原理,顺便带着大家详细理解一下Java程序的执行的内存原理。

3.1 数组的执行原理,Java程序的执行原理

我们以下面的代码,来讲解变量、数组的执原理。

public class ArrayDemo1 {
    public static void main(String[] args) {
        int a = 10;
        System.out.println(a);

        int[] arr = new int[]{11, 22, 33};
        System.out.println(arr);

        System.out.println(arr[1]);

        arr[0] = 44;
        arr[1] = 55;
        arr[2] = 66;

        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);
    }
}

前面我们给大家讲过,程序是在内存中执行的。实际上Java程序是把编译后的字节码加载到Java虚拟机中执行的。

Java为了便于虚拟机执行Java程序,将虚拟机的内存划分为 方法区、栈、堆、本地方法栈、寄存器 这5块区域。同学们需要重点关注的是 方法区、栈、堆

下面把每一个块内存区域作用介绍一下,我们大致只需要知道每一部分存储什么内容就行。

  • 方法区:字节码文件先加载到这里
  • :方法运行时所进入的内存区域,由于变量在方法中,所以变量也在这一块区域中
  • :存储new出来的东西,并分配地址。由于数组是new 出来的,所以数组也在这块区域。

下面是上面案例执行的内存原理如下图所示,按照① ② ③ ④ ⑤ ⑥ 的标记的顺序来看

总结一下int a = 10与 int[] arr = new int[]{11,22,33}的区别

  • a是一个变量,在栈内存中,a变量中存储的数据就是10这个值。
  • arr也是一个变量,在栈中,存储的是数组对象在堆内存中的地址值
// 这里的int a是一个基本类型变量,存储的是一个数值
int a = 10 ; 
//这里的int[] arr是一个引用类型的变量,存储的是一个地址值
int[] arr = new int[]{44,55,66};

3.2 多个变量指向同一个数组的问题

各位同学,我们了解了数组在内存中的执行原理。我们知道数组类型的变量,指向的是堆内存中数组对象的地址。但是在实际开发中可能存在一种特殊情况,就是多个变量指向同一个数组对象的形式。

讲解这个知识点的目的,是让同学们注意多个变量指向同一个数组对象存在什么问题?

我们先看一段代码

public class ArrayDemo2 {
    public static void main(String[] args) {
        // 目标:认识多个变量指向同一个数组对象的形式,并掌握其注意事项。
        int[] arr1 = {11, 22, 33};

        // 把int类型的数组变量arr1赋值给int类型的数组变量arr2
        int[] arr2 = arr1;

        System.out.println(arr1);
        System.out.println(arr2);

        arr2[1] = 99;
        System.out.println(arr1[1]);

        arr2 = null; // 拿到的数组变量中存储的值是null
        System.out.println(arr2);

        //System.out.println(arr2[0]);
        //System.out.println(arr2.length);
    }
}

我们重点关注这一段代码

刚执行完int[] arr1 = {11,22,33};时,内存原理如下

当执行完int[] arr2 = arr1;后,内存原理如下

当执行到arr2[1]=99;时,内存原理如下

总结一下:

  • 两个变量指向同一个数组时,两个变量记录的是同一个地址值。

  • 当一个变量修改数组中的元素时,另一个变量去访问数组中的元素,元素已经被修改过了。

到这里有关数组的基本操作,和内存原理我们就全部学习完了。

四、数组专项练习

接下来我们做一些专项练习题,把数组的常见操作练习一下。在学习这个案例时,重点掌握数组求最值的思路,代码只是用来表达你的思路的。

4.1 数组求最值

需求:定义一个int类型数组,求数组中元素的最大值,并打印最大值

我们先看一下选美比赛,是怎么选出颜值最高的人的。然后再以此思路,来写代码找出数组中元素的最大值。

数组求最大值思路:
	1)先找出数组中0索引的元素,假设为最大值,用max表示【擂主】
	2)遍历后面的每一个元素和max比较,把较大的元素值重新赋值给max(擂主换人)
    3)最后max就是所有元素的最大值(最后站在台上的擂主)
public class Test1 {
    public static void main(String[] args) {
        // 1、把颜值数据拿到程序中来,用数组装起来
        int[] faceScores = {15, 9000, 10000, 20000, 9500, -5};

        // 2、定义一个变量用于最终记住最大值。
        int max = faceScores[0];

        // 3、从数组的第二个位置开始遍历。
        for (int i = 1; i < faceScores.length; i++) {
            // i = 1  2  3  4  5
            // 判断一下当前遍历的这个数据,是否大于最大值变量max存储的数据,
            //如果大于,当前遍历的数据需要赋值给max
            if(faceScores[i] > max ){
                max = faceScores[i];
            }
        }
        System.out.println("最高颜值是:" + max);
    }
}

总结一下:

通过这个案例,我们主要掌握求最值的思路,以后不管遇到求最大值还是最小值,编程思路都是一样的,不同的可能是数据不同。

4.2 数组元素反转

需求:某个数组有5个数据:10,20,30,40,50,请将这个数组中的数据进行反转。
      [10, 20, 30, 40, 50]  反转后 [50, 40, 30, 20, 10]

数组元素反转的核心,其实是数组中两个数据的交换。我们可以认为两个数据分别存储在两个水杯中。想要交换两个水杯中的东西,我们得借助第三个水杯,如下图所示

数组中元素交换,就是用的借用第三方变量的思想。 我们把数组中的每一个元素当做一个水杯,然后索引控制哪两个元素互换位置。

怎么样,才能达到元素反转的效果呢?我们只需将第一个和最后一个元素互换、第二个和倒数第二个互换、依次内推… 如下图所示

怎么样写代码,才能达到上面的效果呢?我们继续分析

1.每次交换,需要有左右两边的两个索引,我们可以用i和j表示
	刚开始i=0,j=数组长度-1;
2.每次让i和j索引位置的两个元素互换位置
	arr[i]和arr[j]互换位置
3.每次还完位置之后,让i往右移动一位,让j往前移动一位

具体代码如下

public class Test2 {
    public static void main(String[] args) {
        // 目标:完成数组反转。
        // 1、准备一个数组
        int[] arr = {10, 20, 30, 40, 50};  

        // 2、定义一个循环,设计2个变量,一个在前,一个在后
        for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
            // arr[i]   arr[j]
            // 交换
            // 1、定义一个临时变量记住后一个位置处的值
            int temp = arr[j];
            // 2、把前一个位置处的值赋值给后一个位置了
            arr[j] = arr[i];
            // 3、把临时变量中记住的后一个位置处的值赋值给前一个位置处
            arr[i] = temp;
        }

        // 3、遍历数组中的每个数据,看是否反转成功了
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

总结一下:

通过上面的案例,需要我们掌握元素互换位置的编程思路;以后遇到数据互换问题,都这样做。

4.3 随机排名

各位同学,通过数组元素反转的案例,我们学会了如何对两个数据进行交换。接下来,我们再学习随机排名案例,将数据交换的思路再巩固一下。

先来看一下需求

需求:某公司开发部5名开发人员,要进行项目进展汇报演讲,现在采取随机排名后进行汇报。请先依次录入5名员工的工号,然后展示出一组随机的排名顺序。

分析一下随机排名的思路

1.在程序中录入5名员工的工号存储起来 ---> 使用动态初始化数组的方式。
2.依次遍历数组中的每个数据。
3.每遍历到一个数据,都随机一个索引值出来,让当前数据与该索引位置处的数据进行交换。

如下图所示,每次遍历到一个元素,随机将当前位置元素和随机索引元素换位置。

代码如下

public class Test3 {
    public static void main(String[] args) {
        // 目标:完成随机排名
        // 1、定义一个动态初始化的数组用于存储5名员工的工号
        int[] codes = new int[5];

        // 2、提示用户录入5名员工的工号。
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < codes.length; i++) {
            // i = 0 1 2 3 4
            System.out.println("请您输入第" + (i + 1) +"个员工的工号:");
            int code = sc.nextInt();
            codes[i] = code;
        }

        // 3、打乱数组中的元素顺序。
        // [12, 33, 54, 26, 8]
        //  i       index
        Random r =  new Random();
        for (int i = 0; i < codes.length; i++) {
            // codes[i]
            // 每遍历到一个数据,都随机一个数组索引范围内的值。
            //然后让当前遍历的数据与该索引位置处的值交换。
            int index = r.nextInt(codes.length); // 0 - 4
            // 定义一个临时变量记住index位置处的值
            int temp = codes[index];
            // 把i位置处的值赋值给index位置处
            codes[index] = codes[i];
            // 把index位置原来的值赋值给i位置处
            codes[i] = temp;
        }

        // 4、遍历数组中的工号输出即可
        for (int i = 0; i < codes.length; i++) {
            System.out.print(codes[i] + " ");
        }
    }
}

到这有关数组的常见练习题我们就讲完了,待会我们在给同学们讲一个开发中用得比较多的工具叫做Debug调试。

五、Debug调试工具

各位同学,为了让大家更好的理解代码的执行流程,这里给大家讲一个在开发中非常重要的工具——叫做Debug调试。

通过Debug调试,我们可以查看代码的执行流程。当你代码中有Bug但是又发现不了的时候,你就可以用Debug调试工具,查看执行流程,逐步分析是哪一行出现了问题。

Debug调试工具的使用步骤如下:

第一步:打断点,如下图的红色小圆点
第二步:右键Debug方式启动程序,如下图右键菜单
	  启动后,代码会停留在打断点的这一行
第三步:点击箭头按钮,一行一行往下执行

以上就是本期 ​​《1个月征服Java:零基础直达企业级开发》​​ 数组篇的全部硬核干货!从​​内存底层的栈堆博弈​​(int[] arr = new int[5]的栈帧谜题)到​​多维矩阵的降维打击​​(二维棋盘/三维空间建模),再到​​算法思维的暴力美学​​(求最值/反转/随机排序三连暴击),我们已铸就​​数据容器的原子核能​​!🚀

👨💻 ​​互动时间​​

⚡️​​内存刺客​​!揪出数组越界的幽灵地址?​​评论区埋雷挑战已就绪​​!
🌱​​转码萌新​​:堆栈指针绕成毛线团?​​私信急救包24小时空投​​!
💙​​(您的每一次三连,都是本码农移植稀疏数组到稠密脑回路的哈希加速器!💥)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值