本专栏为 JavaSE 的学习笔记及相关项目,专栏长期免费更新 ❤️ ❤️ ❤️
⭐️往期回顾:
- 【JavaSE】Java中的流程控制(分支控制、循环控制、嵌套)
- 【JavaSE】【计算机系统基础】原码、反码、补码及位运算详解(重点)
文章目录
1 数组引入
✈️ 数组是 Java 里的引用数据类型,可以存放多个同一类型的数据,通俗点来说,数组就是一组数据。
1.1 数组的使用
⭐️star 1: 动态初始化
方式一:声明的同时分配存储空间
数据类型
[ ]
数组名
=
new
数据类型
[ 大小 ];
方式二:先声明后分配存储空间
数据类型
数组名
[ ];
数组名
=
new
数据类型
[ 大小 ];
比如我们需要创建一个含有五个元素的数组,每个元素都用于存储学生的成绩,示例代码如下:
Scanner in =newScanner(System.in);// 声明数组并开辟空间double[] score =newdouble[5];// 赋值for(int i =0; i <5; i++){
score[i]= in.nextDouble();}
上述代码声明了一个长度为5的数组score,其中score[ 0 ]指向第一个元素,依此类推,注意,在数组中,索引是从 0 开始的,示意图如下:
⭐️star 2: 静态初始化
适用于知道数组具体有多少元素和具体值的情况。
数据类型
数组名
[ ] = {
元素值1
,
元素值2
,
元素值3
… …};
1.2 数组的注意事项
- ⭐️ 数组是多个相同类型数据的组合,实现对数据的统一管理,如果声明了 int 类型的数组,那么其元素值均为 int 类型,但是其也满足类型转换规则,如下代码是可以编译通过的:
double[] number ={12.3,1.23,2.44,100};// 符合自动类型转换
⭐️ 数组中的元素可以是基本数据类型与引用数据类型,但是不可以混用,比如 String 类型的数组中不能存在 int 类型元素;
⭐️ 如果数组创建后没有进行赋值,则会使用默认值,具体如下表:
数据类型默认值int0short0byte0long0float0.0double0.0booleanfalseStringnull⭐️ 数组属于引用类型,数组型的数据是对象。
1.3 数组的赋值机制
1.3.1 基础数据类型的值拷贝
我们先来讨论一下基础数据类型的赋值机制,观如下代码:
publicclassMain{publicstaticvoidmain(String[] args){int a =10;int b = a;
b =20;System.out.println("a = "+ a);System.out.println("b = "+ b);}}
🍑 代码运行结果为 a = 10,b = 20,可见 a 没有受到 b 的影响,我们把这种赋值机制叫做 值拷贝。
1.3.2 数组的引用传递
🍑 数组在默认情况下是引用传递,赋的值是地址,赋值方式为引用传达。
一脸懵? 没关系,我们直接看代码:
publicclassMain{publicstaticvoidmain(String[] args){int[] array1 ={1,2,3,4,5};int[] array2 = array1;// 把 array1 赋给 array2
array2[0]=1000;// 修改 array2// 输出 array1System.out.print("array1 : ");for(int i =0; i < array1.length; i++){System.out.print(array1[i]+" ");}}}
🍎 结果如下图:
通过观察输出结果我们发现,明明我们修改的是 array2 数组的值,可 array1 也受到了影响,这种传值机制就是所谓的引用传递,下面我们来细说:
✈️ 在Jvm中,内存大致被分为3块,栈、堆和方法区。当我们声明数组并初始化 array1 时,jvm 在堆开辟了数组大小的空间,而在栈内存中则存储着指向堆空间的地址,可以理解为门牌号。而这个变量存储的值就是门牌号,当我们将 array1 赋值给了 array2 时,相当于告诉了 array2 :“array1 的地址我告诉你了奥!” 这时,arrray2 便也指向了 array1 开辟的那一部分空间,因此我们修改 array2 的值的时候,实际上是更改了 array1 的值(array1 与 array2 指向同一块儿内存!)。具体示意图如下:
2 数组的拷贝
✈️ 我们了解到数组的赋值方式为引用传递,那么,我们该如何拷贝数组其不会影响原数组的值呢?下面我们来看一段代码,这段代码实现了对 array1 数组的拷贝:
publicclassMain{publicstaticvoidmain(String[] args){int[] array1 ={1,2,3,4,5};// 创建一个新数组 array2, 并开辟新的空间// 大小为 array1.lengthint[] array2 =newint[array1.length];// 数组拷贝for(int i =0; i < array1.length; i++){
array2[i]= array1[i];}// 修改 array2[0]
array2[0]=1000;// 输出 array1 array2System.out.print("array1 : ");for(int i =0; i < array1.length; i++){System.out.print(array1[i]+" ");}System.out.print("\narray2 : ");for(int i =0; i < array2.length; i++){System.out.print(array2[i]+" ");}}}
🍎 实现结果如下:
此时,我们发现,修改 array2 的元素值对 array1 就不会产生影响了,这与之前引用传递的不同是:我们重新给 array2 开辟了新的空间,示意图如下:
3 数组反转
🍑 给定一个数组 array = {1,2,3,4,5,6},让你把它反转,即改为 array = {6,5,4,3,2,1} 你有什么思路吗?
参考思路如下:
- ⭐️ array[ 0 ] 与 array[ 5 ] 进行交换,结果为{6,2,3,4,5,1};
- ⭐️ array[ 1 ] 与 array[ 4 ] 进行交换,结果为{6,5,3,4,2,1};
- ⭐️ array[ 2 ] 与 array[ 3 ] 进行交换,结果为{6,5,4,3,2,1};
- ⭐️ 一共交换了 array.length/2 次, 且每次交换的元素为 array[ i ] 与 array[ length -1 - i]
🍑 参考代码:
publicclassArrayReverse{publicstaticvoidmain(String[] args){int[] array ={1,2,3,4,5,6};for(int i =0; i < array.length/2; i++){int temp = array[i];
array[i]= array[array.length -1- i];
array[array.length -1- i]= temp;}// 输出结果for(int i =0; i < array.length; i++){System.out.print(array[i]+" ");}}}
以上仅仅是一种实现方式,小伙伴们也可以尝试上面讲过的数组拷贝的方法,逆序拷贝 array1 也可以实现同样的功能哦!
4 数组扩容
🍑 我们来看一个实际需求:
要求实现动态给数组添加元素的效果,实现对数组的扩容:
1)原数组使用静态分配,int[ ] arr = {1, 2, 3};
2) 添加的新元素直接放到数组最后 arr = {1, 2, 3, 4}
🍑 参考思路如下:
- ⭐️ 定义初始数组 arr;
- ⭐️ 定义一个新的数组 arrNew;
- ⭐️ 遍历 arr 数组,一次将元素拷贝给 arrNew;
- ⭐️ 将 4 赋值给 arNew[ arrNew.length - 1]
看到这,你可能会有些疑惑:什么?定义一个新数组???这不是浪费空间吗??
不用担心!!!Java 的垃圾回收机制会帮你解决,我们来看下面的示意图:
我们将扩容后的新数组 arrNew 赋值给 arr ,则原数组 arr 开辟的空间
0x0011
未被使用,因此被垃圾回收释放,此时我们再通过 arr 访问的实质上是 arrNew 开辟的新空间!!!
🍎 话不多说!看代码!!
publicclassArrayAdd{publicstaticvoidmain(String[] args){int[] arr ={1,2,3};int[] arrNew =newint[arr.length +1];// 数组拷贝for(int i =0; i < arr.length; i++){
arrNew[i]= arr[i];}
arrNew[arr.length]=4;// 原数组扩容
arr =arrNew;// 查看结果for(int i =0; i < arr.length; i++){System.out.print(arr[i]+" ");}}}
🌟 结果:
4.1 数组动态扩容
🍎 我们可以思考一下,如果上述的需求需要我们不停的添加元素,直到用户希望退出时打印结果,我们该如何优化?
这里可以结合我们上一篇所学的
do while
+
break
实现,程序直接进入循环询问需要添加的元素,添加后询问是否退出,当输入 n 时,退出程序并打印结果,具体代码如下:
importjava.util.Scanner;publicclassArrayAdd{publicstaticvoidmain(String[] args){int[] arr ={1,2,3};Scanner in =newScanner(System.in);do{int[] arrNew =newint[arr.length +1];// 数组拷贝for(int i =0; i < arr.length; i++){
arrNew[i]= arr[i];}System.out.println("输入需要添加的元素: ");int number = in.nextInt();
arrNew[arr.length]= number;// 原数组扩容
arr =arrNew;// 是否需要继续扩容System.out.println("是否继续?(y/n): ");if(in.next().charAt(0)=='n')break;}while(true);System.out.println("结果为: ");// 查看结果for(int i =0; i < arr.length; i++){System.out.print(arr[i]+" ");}}}
😎 实现结果:
写在最后
🌟以上便是本文的全部内容啦,后续内容将会持续免费更新,如果文章对你有所帮助,麻烦动动小手点个赞,非常感谢 ❤️ ❤️!
如果有问题,欢迎私信或者评论区!
共勉:“其实一直陪伴你的,是那个了不起的自己。”
版权归原作者 Nezuko627 所有, 如有侵权,请联系我们删除。