Tips:样式蚂蚁森林浇水get

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);
    }
}
getMax

数组反转

  数组的反转:数组中元素颠倒顺序,例如原始数组元素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);
    }
}
Array作为参数传递

 

 

 数组作为方法返回值

  数组作为方法的返回值,返回的也是数组的内存地址

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;
    }
}
Array作为方法返回值

 

方法的参数类型区别 

  普通参数 

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

  

 

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

 

posted @ 2021-03-03 20:16  心岛未晴  阅读(133)  评论(0)    收藏  举报