java基础——day04-2 内存与数组操作
内存与数组操作
内存
内存概述
内存是计算机的重要元件,临时存储区域,作用是运行程序。我们编写的源代码存储在硬盘中,要运行的话需要通过内存,运行完毕后会清空内存。
JVM的内存划分
为了提高运算效率,Java对空间进行了不同区域的划分,每一片区域都有特定的处理数据方式和内存管理方式。

关于栈 与 堆
栈区(stack)— 由编译器自动分配释放 ,存放函数参数值,局部变量值等。其操作方式类似于数据结构中的栈。
堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。
数组在内存中的存储
package day04; public class day04_7 { //查看数组在内存中的存储 public static void main(String[] args) { int[] arrayList = new int[3]; //此打印输出会输出一个内存地址 [I@6d6f6e28 System.out.println(arrayList); } }
以上方法执行后,输出结果是 [I@6d6f6e28 ,这是数组在内存中的地址。new出来的内容,都是在堆内存中存储的,而方法中的变量arrayList保存的是数组的地址。
一个数组的内存图

package day04; public class day04_8 { public static void main(String[] args) { /** * 定义动态整型数组 * 定义变量 arr 用于存储数组的地址值 * 数组长度为3 能够存储三个整型元素 */ int[] arr = new int[3]; //打印输出数组 返回一个十六进制地址值 [I@6d6f6e28 System.out.println(arr); } }
两个数组的内存图
package day04; public class day04_9 { public static void main(String[] args) { //定义数组1 通过变量arr1保存数组地址 长度为3 int[] arr1 = new int[3]; //定义数组2 通过变量arr1保存数组地址 长度为2 int[] arr2 = new int[2]; //打印输出 结果[I@6d6f6e28 System.out.println(arr1); //打印输出结果 [I@135fbaa4 System.out.println(arr2); //发现两个地址值并不相同,因为两个数组都是new出来的 相当于在堆内存中 开辟了两块空间 } }

两个变量指向同个数组
package day04; public class java04_10 { public static void main(String[] args) { //定义一个数组 存储三个元素 int[] arr = new int[3]; //通过索引为其赋值 arr[0] = 5; arr[1] = 6; arr[2] = 7; //输出三个索引元素值 for (int i = 0; i < arr.length; i++) { System.out.println(i+"号元素的值为:"+arr[i]); } //定义数组变量arr2 将arr的地址赋值给arr2 int[] arr2 = arr; System.out.println(arr2[1]); System.out.println(arr[1]); //通过输出结果可发现 两个数组的1号元素都是6 //打印输出arr 与arr2的地址 其地址都指向[I@6d6f6e28 System.out.println(arr); System.out.println(arr2); } }

数组的常见操作
数组越界异常
package day04; public class day04_11 { //关于越界异常 public static void main(String[] args) { //定义长度为3 可存储三个元素的 动态数组 int[] arr = new int[3]; //打印输出数组的第四号元素 此处无异常 System.out.println(arr[3]); /** * 当我们编译输出后 控制台 显示 * Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 * at day04.day04_11.main(day04_11.java:7) * * 指的是,线程在"main"中出现异常,在程序中出现 数组索引超出范围异常 * 原因:因为定义的数组长度为三 索引有0 1 2 三个 并没有3的索引 索引产生了越界 */ } }
注意:在开发中,数组的越界异常是不能出现的,一旦出现,就必须修改我们的代码
数组空指针异常
package day04; public class day04_12 { //解析空指针异常 public static void main(String[] args) { //定义可存储三个元素的动态数组 int[] arr = new int[3]; //打印未赋值的arr 控制台打印出 [I@6d6f6e28 这个地址值 System.out.println(arr); System.out.println("=================="); //将数组赋值为null arr = null; //打印输出 arr 发现地址值为null 空了 System.out.println(arr); //打印输出 数组arr 索引为0的元素 控制台报出 java.lang.NullPointerException 空指针异常 System.out.println(arr[0]); } }
注意:在开发中,数组的越界异常是不能出现的,一旦出现,就必须修改我们的代码
空指针异常在内存图中的表现:

数组的遍历[重点]
定义:就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石。
package day04; public class day04_13 { //非遍历数组 public static void main(String[] args) { int[] arrList = {1,3,5,7,9}; //一个个输出 System.out.println(arrList[1]); System.out.println(arrList[2]); System.out.println(arrList[3]); System.out.println(arrList[4]); System.out.println(arrList[5]); } }
package day04; public class day04_13 { //非遍历数组 public static void main(String[] args) { int[] arrList = {1,3,5,7,9}; //一个个输出 for (int i = 0; i < arrList.length; i++) { System.out.println("我是数组下标为第"+i+"的元素,值为:"+arrList[i]); } } }
以上代码,非遍历是将数组的每个元素都打印输出,但是若元素非常多,会造成代码冗余。而通过遍历,我们不仅可以减少代码量,也能更高效的取出元素中的元素。
数组获取最大元素
package day04; public class day04_14 { //获取数组中的最大值 public static void main(String[] args) { //静态定义一个数组 int[] arrList = {1,7,5,10,4,6,9}; //定义一个变量接收最大值 先将数组的第一个元素看做是最大值 int max = arrList[0]; //遍历数组 for (int i = 0; i < arrList.length; i++) { //首先 0号元素和1号元素对比 如果max<arrList[i]号元素 将arrList[i]号元素的值 赋给max if(max < arrList[i]){ max = arrList[i]; } } //打印输出最大值 System.out.println(max); } }
数组反转
数组的反转:数组中元素颠倒顺序,例如原始数组元素1,2,3,4,5 反转为5,4,3,2,1
实现思路:
1.实现反转就需要将数组最远端的元素位置交换
2.定义两个变量,保存数组最大索引与最小索引
3.两个索引上的元素交换位置
4.最小索引++ 最大索引-- 再次交换位置
5.最小索引超过了最大索引,数组反转结束

package day04; public class day04_16 { //反转数组 public static void main(String[] args) { //定义静态数组 int[] arr = {1,2,3,4,5,6}; /**解析,min=0 指的是索引开始的位置;max= arr.lenth-1就是数组的最大索引 * min <= max 指的是数组的索引对比的位置 当比较到max<=min时 对比结束 * min++ 指的是数组开始元素 开始递增 max--指的是数组最大值位置 开始递减 */ for (int min = 0,max = arr.length-1; min <= max; min++,max--) { //定义一个变量 作为篮子 将数组的最小元素装进去 int temp = arr[min]; //将数组的最大索引的元素,赋值给最小索引 arr[min] = arr[max]; //将篮子里的最小值 赋值给数组的最大索引 arr[max] = temp; } //循环遍历输出反转后的数组 for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } }
数组作为方法参数的返回值
数组作为方法参数
之前学了方法的参数和返回值(八种基本数据类型)。其实数组也可以作为方法的返回参数。
数组作为方法参数传递,传递的参数是数组的内存地址。
package day04; public class day04_17 { //数组作为返回值 public static void main(String[] args) { //定义静态数组 int[] arrList = {1,2,3,4,5}; //调用方法 将数组作为参数传递 printArr(arrList); //查看数组的地址 发现其都指向同一个内存地址 [I@6d6f6e28 System.out.println(arrList); } //定义方法 方法的功能 遍历打印数组 public static void printArr(int[] arr){ for (int i = 0; i < arr.length;i++){ System.out.println("我是被调用的"+i+"号元素,我的值为"+arr[i]); } //查看数组的地址 System.out.println(arr); } }

数组作为方法返回值
数组作为方法的返回值,返回的也是数组的内存地址
package day04; public class day04_18 { //数组作为方法返回值 public static void main(String[] args) { //定义数组变量 用于接收方法返回值 int[] arrList = getArray(); for (int i = 0; i < arrList.length; i++) { System.out.println(arrList[i]); } //查看数组地址 [I@6d6f6e28 System.out.println(arrList); } //创建方法 返回数组类型 public static int[] getArray(){ //定义静态数组 int[] arr = {2,4,6,8,10}; //查看数组地址 [I@6d6f6e28 System.out.println(arr); return arr; } }

方法的参数类型区别
普通参数
package day04; public class day04_19 { public static void main(String[] args) { int a = 10; int b = 20; //输出 a b值 System.out.println(a); System.out.println(b); //调用方法 change(a,b); //调用后 输出a b值 System.out.println(a); System.out.println(b); } public static void change(int a,int b){ //此方法无返回值 所以结果不会返回到调用者 a = a+b; b = b+a; } }
数组参数
package day04; public class day04_20 { public static void main(String[] args) { int[] arrList = {1,3,5,7,9}; //输出 数组下标为2的元素 System.out.println(arrList[2]); //调用方法 将数组传递给change方法 change(arrList); //打印输出调用后的 下标为2的元素值 发现其值已经改变 理由是数组作为方法的参数 传递的是地址值 System.out.println(arrList[2]); } //定义方法 public static void change(int[] arr){ //在方法内修改 传递过来的数组 下标为2的元素值 arr[2] = 200; } }
总结:方法的参数为基本类型时,传递的是数据类型。
方法的参数为引用类型时,传递的是地址值。
关于基本类型和引用类型
八种基本类型:byte,char,short,int,float,double,char,boolean

引用类型:所有的对象,包括数组都是引用类型

浙公网安备 33010602011771号