数组是什么?
学完循环之后,紧接着就遇到了数组。说实话,刚开始我有点懵——明明单个变量用着挺顺手的,为啥非要搞个数组出来?直到有一天,老师让我们存50个学生的成绩。用单个变量?score1、score2……写到score50?手都得废掉。数组就是来解决这个问题的——把一堆相同类型的数据整整齐齐地排在一起,用同一个名字,通过下标来区分。打个比方:变量就像一个个独立的盒子,每个盒子有自己的名字;数组就像一排连在一起的储物柜,整体叫一个名字,每个小格子编个号(下标)。
怎么定义一个数组?
最基础的写法:
int[]arr=newint[5];// 一个能装5个整数的数组这行代码干了三件事:声明了一个数组变量、在内存里划了一块连续的空间、把地址赋给了变量。
还有两种偷懒的写法:
// 方式一:声明时直接赋值int[]arr1={10,20,30,40,50};// 方式二:先声明再初始化int[]arr2;arr2=newint[]{1,3,5,7,9};踩坑提醒:数组一旦定义,长度就固定了。想改大小?对不起,重新建一个吧。
下标:从0开始,不能越界
数组的下标从0开始,到length-1结束。
int[]arr={10,20,30,40};System.out.println(arr[0]);// 10,第一个元素System.out.println(arr[3]);// 40,最后一个元素System.out.println(arr[4]);记住一个口诀:数组长度是N,下标范围0到N-1。
length属性可以随时获取数组长度,遍历时用i < arr.length而不是i <= arr.length,能有效避免越界。
遍历数组:两种方式
普通for循环
int[]arr={10,20,30,40,50};for(inti=0;i<arr.length;i++){System.out.println(arr[i]);}需要用到下标时就选这个,比如要修改某个位置的元素。
增强for循环
for(intnum:arr){System.out.println(num);}代码更简洁,但只能读不能改。适合只需要查看元素内容的场景。
找最值
找数组里的最大值或最小值,思路很简单——先假设第一个元素就是答案,然后挨个比较,发现有更好的就替换。
int[]arr={20,27,5,3,18,32,16};intmax=arr[0];for(inti=1;i<arr.length;i++){if(arr[i]>max){max=arr[i];}}System.out.println("最大值:"+max);
这个思路在其他地方也能用,比如找第二名、找最小的,套路都一样。
动态扩容:数组不够用了怎么办?
数组定长是个硬伤。实际开发中经常不知道要存多少数据,比如学生管理系统,学生数量是动态变化的。
解决方案:满了就新建一个更大的数组,把原来的数据拷过去。
int[]arr=newint[3];// 存数据的过程中发现满了...arr=Arrays.copyOf(arr,arr.length+3);// 扩容3个位置冒泡排序
排序是数组操作里的重头戏,冒泡排序是最基础的一种。核心思想:相邻元素两两比较,大的往后“冒”。
int[]arr={20,4,16,32,12,6,18,69,34};for(inti=0;i<arr.length-1;i++){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;}}}Arrays.sort(arr)
当然,实际工作中没人手写冒泡,直接用Arrays.sort(arr)一行搞定。但理解排序的思想比记住API更重要。
总结
数组是Java里最基础的数据结构,但千万别因为它简单就轻视。理解数组,本质上是在理解内存的连续分配和下标访问机制,这是后面学集合、学算法的基础。