news 2026/3/27 23:00:34

【Java SE 基础学习打卡】36 数组的常见操作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Java SE 基础学习打卡】36 数组的常见操作

目录

  • 前言
  • 一、数组元素的查找:线性查找(翻收纳盒找东西)
    • 1.1 生活化类比
    • 1.2 核心原理
    • 1.3 代码示例(找指定成绩,返回索引)
    • 1.4 线性查找的特点(新手记)
  • 二、数组元素的排序:冒泡排序(让大元素 “浮” 到末尾)
    • 2.1 生活化类比
    • 2.2 核心原理(升序排序)
    • 2.3 基础代码实现(冒泡排序升序)
    • 2.4 冒泡排序优化(避免无效循环)
  • 三、数组元素的增删改:长度固定也能 “灵活操作”
    • 3.1 最简单:元素修改(直接替换)
    • 3.2 数组新增元素(扩容思路)
    • 3.3 数组删除元素(前移覆盖)
    • 3.4 关键提醒:数组增删的本质
  • 四、数组的拷贝:System.arraycopy ()(备份收纳盒)
    • 4.1 方法参数详解(新手记牢)
    • 4.2 代码示例(拷贝全部 / 部分元素)
    • 4.3 应用场景(新手常用)
    • 4.4 避坑提醒:数组拷贝的边界校验
  • 五、新手必避的 5 个 “操作致命坑”
    • 5.1 坑 1:冒泡排序内层循环条件写错
    • 5.2 坑 2:新增 / 删除元素时直接修改原数组
    • 5.3 坑 3:线性查找返回布尔值,不返回索引
    • 5.4 坑 4:数组拷贝时目标数组未初始化
    • 5.5 坑 5:删除元素时忽略索引合法性校验
  • 总结

前言

上一节咱们掌握了数组元素的访问和遍历,现在要落地到实际编程场景:比如从成绩数组里找有没有 95 分的学生(查找)、把成绩按从低到高排好序(排序)、给数组新增一个学生成绩(新增)、删掉无效的成绩(删除)、备份一份成绩数组(拷贝)。

新手容易觉得 “数组长度固定” 就没法增删元素,也容易被冒泡排序的 “相邻交换” 绕晕,这一节咱们就用 “整理收纳盒里的东西” 作为类比,把数组的查找、排序、增删改、拷贝这 4 个核心操作讲透,每个操作都给可运行的代码,还会讲优化思路和避坑点,让新手能直接落地使用!

一、数组元素的查找:线性查找(翻收纳盒找东西)

数组查找是 “从一堆元素里找指定值”,最基础的是线性查找(也叫顺序查找),适合无序数组,原理简单易懂。

1.1 生活化类比

想从装满成绩纸条的收纳盒里找 “95 分” 的纸条:

  • 从第一个纸条开始,逐个打开看;

  • 找到就停下,没找到就翻到最后一个;

  • 核心:按顺序遍历,逐个匹配,适合杂乱的收纳盒(无序数组)。

1.2 核心原理

遍历数组的每个元素,和目标值逐一比较:

  • 匹配成功:返回该元素的索引;

  • 遍历结束仍未匹配:返回 - 1(约定俗成的 “未找到” 标识)。

1.3 代码示例(找指定成绩,返回索引)

publicclassArraySearch{// 线性查找方法:arr是数组,target是要找的目标值publicstaticintlinearSearch(int[]arr,inttarget){// 遍历数组,逐个匹配for(inti=0;i<arr.length;i++){if(arr[i]==target){returni;// 找到,返回索引}}return-1;// 没找到,返回-1}publicstaticvoidmain(String[]args){int[]scores={90,85,95,88,92};inttarget=95;intindex=linearSearch(scores,target);if(index!=-1){System.out.println("找到"+target+"分,索引是:"+index);}else{System.out.println("没找到"+target+"分");}}}

执行结果:

找到95分,索引是:2

1.4 线性查找的特点(新手记)

  • 优点:简单,无需数组有序,代码易写;

  • 缺点:效率低,数组越长,遍历次数越多(最坏要遍历全部元素);

  • 适用场景:小容量数组、无序数组。

二、数组元素的排序:冒泡排序(让大元素 “浮” 到末尾)

排序是把数组元素按指定顺序(升序 / 降序)排列,冒泡排序是新手必学的基础排序算法,核心是 “相邻元素比较交换,大的元素逐步往后移,像气泡上浮一样”。

2.1 生活化类比

把收纳盒里的成绩纸条按 “从低到高” 摆好:

  • 从第一个纸条开始,和旁边的纸条比,分数高的往右挪;

  • 第一轮比完,最高分的纸条会到最右边(像气泡浮到顶部);

  • 第二轮只比前 n-1 个纸条,确定次高分的位置;

  • 重复直到所有纸条排好。

2.2 核心原理(升序排序)

  1. 外层循环:控制排序轮数,共需数组长度-1轮(最后一个元素不用比);

  2. 内层循环:每轮遍历未排序的元素,相邻元素比较,若前 > 后则交换;

  3. 每轮结束:当前未排序部分的最大值 “浮” 到末尾。

2.3 基础代码实现(冒泡排序升序)

publicclassArrayBubbleSort{// 冒泡排序方法:传入int数组,按升序排序publicstaticvoidbubbleSort(int[]arr){// 外层循环:控制轮数,共arr.length-1轮for(inti=0;i<arr.length-1;i++){// 内层循环:每轮比较到“未排序的最后一位”,即arr.length-1-ifor(intj=0;j<arr.length-1-i;j++){// 前一个元素 > 后一个,交换位置(升序)if(arr[j]>arr[j+1]){// 临时变量存值,完成交换inttemp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}}}publicstaticvoidmain(String[]args){int[]scores={90,85,95,88,92};System.out.println("排序前:");for(intscore:scores){System.out.print(score+" ");// 输出:90 85 95 88 92}bubbleSort(scores);// 调用排序System.out.println("\n排序后(升序):");for(intscore:scores){System.out.print(score+" ");// 输出:85 88 90 92 95}}}

2.4 冒泡排序优化(避免无效循环)

如果数组提前排好序,基础版还会继续循环,优化思路:加 “是否交换” 的标志位,没交换说明已排好,直接结束。

publicstaticvoidbubbleSortOptimize(int[]arr){for(inti=0;i<arr.length-1;i++){booleanisSwapped=false;// 标志位:本轮是否交换过for(intj=0;j<arr.length-1-i;j++){if(arr[j]>arr[j+1]){inttemp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;isSwapped=true;// 标记有交换}}if(!isSwapped){break;// 本轮没交换,说明已排好,直接退出}}}

三、数组元素的增删改:长度固定也能 “灵活操作”

数组长度一旦创建就不能改,但可以通过 “新建数组 + 拷贝元素” 实现增删,修改则直接通过索引赋值即可。

3.1 最简单:元素修改(直接替换)

修改是数组最基础的操作,直接通过 “数组名 [索引] = 新值” 替换,无需复杂逻辑。

publicclassArrayModify{publicstaticvoidmain(String[]args){int[]scores={90,85,95};// 修改索引1的元素(85分→92分)scores[1]=92;System.out.println("修改后数组:");for(intscore:scores){System.out.print(score+" ");// 输出:90 92 95}}}

3.2 数组新增元素(扩容思路)

核心逻辑:新建一个 “长度 + 1” 的数组,拷贝原数组所有元素,最后把新元素放到末尾。

publicclassArrayAdd{// 数组新增元素:arr原数组,newVal新增值publicstaticint[]addElement(int[]arr,intnewVal){// 1. 新建长度+1的数组int[]newArr=newint[arr.length+1];// 2. 拷贝原数组元素到新数组for(inti=0;i<arr.length;i++){newArr[i]=arr[i];}// 3. 新元素放到新数组末尾newArr[arr.length]=newVal;// 4. 返回新数组(原数组不变)returnnewArr;}publicstaticvoidmain(String[]args){int[]scores={90,85,95};int[]newScores=addElement(scores,88);// 新增88分System.out.println("新增后数组:");for(intscore:newScores){System.out.print(score+" ");// 输出:90 85 95 88}}}

3.3 数组删除元素(前移覆盖)

核心逻辑:找到要删除元素的索引,把该索引后面的元素逐个往前移,最后把末尾元素置为默认值(或新建长度 - 1 的数组)。

publicclassArrayDelete{// 数组删除元素:arr原数组,delIndex要删除的索引publicstaticint[]deleteElement(int[]arr,intdelIndex){// 校验索引合法性if(delIndex<0||delIndex>=arr.length){System.out.println("索引不合法,删除失败");returnarr;}// 1. 新建长度-1的数组int[]newArr=newint[arr.length-1];// 2. 拷贝删除索引前的元素for(inti=0;i<delIndex;i++){newArr[i]=arr[i];}// 3. 拷贝删除索引后的元素(往前移一位)for(inti=delIndex;i<newArr.length;i++){newArr[i]=arr[i+1];}returnnewArr;}publicstaticvoidmain(String[]args){int[]scores={90,85,95,88};int[]newScores=deleteElement(scores,2);// 删除索引2的95分System.out.println("删除后数组:");for(intscore:newScores){System.out.print(score+" ");// 输出:90 85 88}}}

3.4 关键提醒:数组增删的本质

数组长度固定,所谓 “增删” 其实是创建新数组 + 拷贝原元素,原数组不会改变,新手不要试图直接修改原数组的长度。

四、数组的拷贝:System.arraycopy ()(备份收纳盒)

数组拷贝是 “复制一份数组的全部 / 部分元素”,Java 提供了System.arraycopy()方法,比手动 for 循环拷贝效率更高。

4.1 方法参数详解(新手记牢)

System.arraycopy(源数组,源起始索引,目标数组,目标起始索引,拷贝长度);
  • 源数组:要拷贝的原数组;

  • 源起始索引:从原数组的哪个索引开始拷贝;

  • 目标数组:拷贝到的新数组;

  • 目标起始索引:新数组从哪个索引开始接收;

  • 拷贝长度:要拷贝的元素个数。

4.2 代码示例(拷贝全部 / 部分元素)

publicclassArrayCopy{publicstaticvoidmain(String[]args){int[]scores={90,85,95,88,92};// 示例1:拷贝全部元素(备份数组)int[]copyAll=newint[scores.length];System.arraycopy(scores,0,copyAll,0,scores.length);System.out.println("拷贝全部元素:");for(intscore:copyAll){System.out.print(score+" ");// 输出:90 85 95 88 92}// 示例2:拷贝部分元素(拷贝索引1到3的元素,共3个)int[]copyPart=newint[3];System.arraycopy(scores,1,copyPart,0,3);System.out.println("\n拷贝部分元素:");for(intscore:copyPart){System.out.print(score+" ");// 输出:85 95 88}}}

4.3 应用场景(新手常用)

  • 数组扩容 / 缩容:新增 / 删除元素时,拷贝原数组元素到新数组;

  • 数组备份:避免原数组修改影响数据;

  • 截取数组片段:只拷贝需要的部分元素。

4.4 避坑提醒:数组拷贝的边界校验

拷贝前要确保:

  • 拷贝长度 ≤ 源数组剩余元素个数(源起始索引 + 拷贝长度 ≤ 源数组长度);

  • 拷贝长度 ≤ 目标数组剩余空间(目标起始索引 + 拷贝长度 ≤ 目标数组长度);否则会抛出ArrayIndexOutOfBoundsException

五、新手必避的 5 个 “操作致命坑”

5.1 坑 1:冒泡排序内层循环条件写错

  • 错误示例:

    // 内层循环没减i,重复比较已排好的元素for(intj=0;j<arr.length-1;j++){}
  • 避坑:固定写j < arr.length - 1 - i,每轮少比较已排好的 i 个元素。

5.2 坑 2:新增 / 删除元素时直接修改原数组

  • 错误示例:

    // 以为能直接给原数组新增元素,实际编译报错scores.length=scores.length+1;
  • 避坑:增删必须创建新数组,原数组长度无法修改。

5.3 坑 3:线性查找返回布尔值,不返回索引

  • 错误示例:

    // 只能判断有没有,没法知道位置,实用性低publicstaticbooleansearch(int[]arr,inttarget){for(inti=0;i<arr.length;i++){if(arr[i]==target)returntrue;}returnfalse;}
  • 避坑:优先返回索引(找到返回索引,没找到返回 - 1),更灵活。

5.4 坑 4:数组拷贝时目标数组未初始化

  • 错误示例:

    int[]copyAll=null;System.arraycopy(scores,0,copyAll,0,scores.length);// 空指针异常
  • 避坑:拷贝前必须初始化目标数组,且长度足够。

5.5 坑 5:删除元素时忽略索引合法性校验

  • 错误示例:

    // 传入负数索引或超出长度的索引,运行时报错deleteElement(scores,-1);
  • 避坑:删除前先校验delIndex >= 0 && delIndex < arr.length

总结

这一节咱们掌握了数组的 4 个核心常见操作,记住 3 个核心点:

  1. 查找:线性查找适合无序数组,找到返回索引、没找到返回 - 1;

  2. 排序:冒泡排序核心是 “相邻比较交换,每轮确定一个最大值”,加标志位可优化;

  3. 增删改拷贝:修改直接赋值,增删需新建数组,拷贝优先用 System.arraycopy ()。

这些操作是数组实操的基础,后续学习二维数组、集合等内容都会用到,掌握好这些,处理批量数据就会更灵活。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/17 5:48:11

2000亿美元!2026年全球游戏行业的新格局与新变量

2000亿美元&#xff01;2026年全球游戏行业的新格局与新变量 2026年&#xff0c;全球游戏市场规模预计突破2000亿美元&#xff08;约2050-2100亿美元&#xff09;&#xff0c;从2025年的1888-1970亿美元增长3-7%。 这标志着后疫情低迷期的复苏&#xff08;增长率从2022-2024的…

作者头像 李华
网站建设 2026/3/25 3:39:27

鸿蒙APP开发从入门到精通:ArkUI组件库详解与常用组件实战

鸿蒙APP开发从入门到精通&#xff1a;ArkUI组件库详解与常用组件实战 鸿蒙&#xff08;HarmonyOS NEXT&#xff09;是华为推出的分布式操作系统&#xff0c;其APP开发框架以ArkUI为核心&#xff0c;采用ArkTS&#xff08;基于TypeScript的扩展语言&#xff09;进行声明式开发。…

作者头像 李华
网站建设 2026/3/24 5:20:56

Router_T000_ConceptMECE

startmindmap* 汇报总图** 动机价值*** 故事钩子*** 价值主张** 现状基线*** 基线速览*** SafeDreamer*** UNISafe外盾*** SPOWL** 问题缺陷*** 主流缺陷*** OOD幻觉*** 外盾不学*** 固定阈值** 创新方案*** 核心创新*** Risk-Bellman*** ucert内生*** 不改环境奖*** 插入点** …

作者头像 李华
网站建设 2026/3/14 13:44:14

Java计算机毕设之基于springboot+vue的游戏装备账号销售商城平台系统基于springboot的游戏售卖商城系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华