Day05 --二维数组

 a.
​    
    一维数组 
        概念
            对数组操作最基本的动作就是存和取。
        核心思想
            就是对角标的操作。
    
        动态初始化
        int[] arr = new int[6]; 
        静态初始化
        int[] arr = new int[]{3,5,66,7,8}; 
        int[] arr = {3,5,66,7,8};
    
        用于存储同种数据类型的多个值。
    概念:
        * 数组是存储同一种数据类型的多个元素的集合,可以看做一个容器。
        * 数组可以是基本数据类型,也可以是引用数据类型。    
    p.s.
    数组的好处:
        可以自动给数组中你的元素从0开始编号,方便操作这些元素。
    
    格式:
        数组类型[] 数组名 = new 数组类型[数组的长度];
            int[] arr  = new int[5];
    解释:
        左边:
          int: 数据类型
           []: 代表数组,[]个中括号,就代表几维数组。
          arr: 数组名,即合法标识符。
        右边:    
          new: 创建一个新的实体或对象
          int: 数据类型
           []: 代表数组
            5: 代表数组的长度,表示能存入几个数据。    


b.
    数组的初始化
        就是为数组开辟连续的内存空间,并为每个数组的元素赋予值。
    如何对数组进行初始化
        初始化分两种:
            * 动态初始化:
                * 只指定长度,由系统给出初始值。
                * 数据类型[] 数组名 = new 数据类型[数组长度];
                * int[] a = new int[5]; 
                * 解释:
                    * 首先会创建new int[5],会记录一个地址值,将地址值给arr。
                    
            * 静态初始化:
                * 给出初始值,根据初始化值的个数,由系统决定长度。
                * 数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
            
    默认初始化值:
        整数类型:byte,short,int,long 默认初始化值都是:0
        浮点类型:float,double 默认初始化值都是:0.0
        Boolean类型: 默认初始化值是false
        字符类型:char,默认初始化值: '\u0000' 
        char在内存中的占2个字节, 是16个二进制位。
        u0000中的每个0代表的是16进制的0,那么四个0就是代表16个二进制。
    
    int[] arr = new int[4];
    System.out.println(arr);  //[I@1db9742
   解释:[I@1db9742
        [:代表数组,几个就代表几维,现在是一个二维数组。
        I:表示是int类型的数据类型。
        @:固定的。    
   1db9742:哈希code地址值,是一个十六值形式的地址值。


    double[] d = new double[5];
    System.out.println(d);  //[D@1db9742
   解释:[D@1db9742
        [ 代表数组,几个就代表几维
        D 表示数据类型
        @ 固定写法
   1db9742 哈希code,代表一个十六进制的地址值。

    p.s.
    java程序在运行的时候,需要在内存中分配空间,为了提高运行效率,又对空间进行了不同区域的划分,因为每一片区域都有特点的处理数据方式和内存管理方式。


c.
    内存的分配 和 栈堆的区别?
      分配:(5个)    
        栈: 存储局部变量
                * 局部变量: 定义在方法声明上或方法中的。
        堆: 存储new出来的数组或对象
     方法区: 面向对象时再说
 本地方法区: 跟系统有关
     寄存器: 给cpu用的

        比如:
            .class文件, javac后,生成一个.class文件,该文件在硬盘中,当java的时候,.class由硬盘进入内存中。 然后程序里面的具体代码,分别进入内存中的分配中,如局部变量进栈,new出来的数字或对象进堆等等等等。
    p.s.
        栈内存:
            用于存储局部变量和方法,当变量和方法所属的作用域一旦结束,所占空间会自动释放。
        堆内存:
            数组和对象,通过new建立的实例都存放在堆内存中。
            每个实体都有内存地址值。
        
        实体中的变量都有默认初始化值,根据类型的不同而不同,如整数类型是0,小数类型是0.0或0.0f,Boolean类型是false,char类型是'\u0000'
            
        如果将数字的引用实体设置为null,也就是实体不再被使用,那么会在不确定的时间内被垃圾号机制给回收掉。    


​    
    静态初始化:
    格式:
        数据类型[] 数据名 = new 数据类型[多少个];
        int[]  arr = new int[6];

例子:
    三个引用,有两个数组的引用指向同一个地址
        int[] arr1 = new int[3]; //[I@da6bf4  
        int[] arr2 = new int[4]; //[I@1eb97b8
        int[] arr3 = arr2; //都是指向同一个地址值,即[I@1eb97b8。
        这就是三个引用,两个数组。


    静态初始化:
    格式:
        数据类型[] 数据名 = new 数据类型[]{元素1,元素2,...};
    简化格式:
        数据类型[] 数据名 = {元素1,元素2,...};
    二者的区别:
        int[] arr = new int[]{5,6,7,8}; //规矩写法
        int[] arr2 = {4,5,6,78};  //简写
    
    分行写:
        规矩写法
        int[] arr;
        arr = new int[]{5,6,7,8}; //正确
        简写
        int[] arr2;    
        arr2 = {4,5,6,78}; //错误
    
    所以说
        规矩写法: 可以先声明,后赋值。
        简写: 只能写在一行。


例子:
    int[] arr = new int[]{1,2,3,4,5};
    int[] arr2 = {6,7,8,9,10};    
        System.out.println(arr);//地址值
        System.out.println(arr[0]);//1
可以写成二行:
    int[] arrs;
    arrs = new int[]{1,2,3,4,5};
    System.out.println(arrs[3]);//4 这里[]中的数字,代表的是索引数。

//只能写一行
    //int[] arrs2;
    //arrs2 = {22,4,55,43};//报错, 只能写成一行。

//不能动静结合
    //int[] arr = new int[5]{1,2,3,4,5};


d.
    数组中存在的问题:
        * 角标越界
            * ArrayIndexOutofBoundsException: 数组索引越界异常
                * 原因: 访问了不存在的索引。
例子:
        int[] arr = new int[6];
        System.out.println(arr[5]); //0
        System.out.println(arr[6]); //报错,因为6是不存在的索引。


        * 空指针
            * 
            * PointerException: 空指针异常
                * 原因:数组越界不在指向堆内存,而你还继续使用该数组名去访问元素。
例子:
        int[] arr2 = new int[5];
        arr2 = null; //因为已被nul已覆盖,地址值不存在了。
        System.out.println(arr2[0]);//不存在,异常。

e.
    数组的遍历
        数组的遍历:就是依次输出数组中的每个元素的值。
        数组的属性:arr.length 数组的长度。
        最大的索引:arr.length-1
    * 最大长度就是最大索引数,即arr.length-1。
例子:
        class Demo6_数组_一维数组的遍历 {
        public static void main(String[] args) {    
            int[] arr = new int[]{33,54,22,53,23};    
            for (int z = 0;z<arr.length ;z++ ) {
               System.out.println(arr[z]);
            }
    
        //使用方法来做
            int[] aa = new int[5];
            int[] bb = new int[]{4,6,7,8,9};
            Arr(aa); // 0 0 0 0 0
            Arr(bb); // 4 6 7 8 9
        }
        
        //使用方法来便利获取多个数组的元素、
        public static void Arr(int[] arrs){
            for (int i = 0;i<arrs.length ;i++ ) {
                    System.out.print(arrs[i]+" ");
            }
        }
    }
    
    p.s.
        数组操作常见问题
            数组角标越界异常:ArrayIndexOfBoundsException: 访问了数组中不存在的角标时而发生的异常。
            空指针异常: NullPointerException: 当引用型变量没有指向任何实体时,用其操作给实体,就会发生这样的异常。



f.
    获取数组中的最大值和最小值
    class Demo7_数组_一维数组_获取数组中的最大值最小值  {
        public static void main(String[] args) {
            
            int[] arr1 = {33,4,5,6,77,88,79};
            int[] arr2 = {55,66,88,90,3,2,1};
            getMax(arr1);
            getMax(arr2);    
    
            getMin(arr1);
            getMin(arr2);
    
        }
        //获取数组中的最大元素
        public static void getMax(int[] arr){
            int max=arr[0]; // 对应初始化值,用于记录元素中的第一个值。
            for (int i =1; i< arr.length ;i++ ) { // 从数组的第二个元素开始遍历。
                if(max<arr[i]){ // 如果max每次记录的数都小于数组中的元素。
                    max = arr[i]; // max就记录较大的值。
                }
            }
            System.out.println("最大值:"+max);
        }


        //获取数组中的最小元素
        public static void getMin(int[] arrs){
            int min = arrs[0]; // 对应初始化值,用于记录元素中的第一个值。
            for (int i =1;i<arrs.length ;i++ ) { // 从数组的第二个元素开始遍历
                if(min>arrs[i]){ // 【如果每次arr[i]中的值都小于min,】
                    min = arrs[i]; // min就记录较小的值。
                }
            }
            System.out.println("最小值:"+min);
            
        }
    }    


g.    
    数组的反转
    class Demo8_数组_一维数组_的反转 {
        public static void main(String[] args) {
            
    /*
        数组元素反转(就是把元素对调)
        i<arr.length/2 表示循环的次数
    */        
        int[] arr = new int[]{33,44,55,66,77,88,99};
        reverse(arr);
        }
    
        public static void reverse(int[] arr){
            
            for (int i = 0; i<arr.length/2; i++ ) {//arr.length/2表示循环的次数:两两交换,是索引的2分之一倍
                //反转过程 根据两个数交换的原理来做, 定义第三方变量。
                /*
                arr[0] 和 arr[arr.length-1-0]交换
                arr[1] 和 arr[arr.length-1-1]交换
                arr[2] 和 arr[arr.length-1-2]交换
                */
                int temp = arr[i]; // 定义临时变量,将arr[i]给临时变量。
                arr[i] = arr[arr.length-1-i]; // arr[1] 和 arr[arr.length-1-1]交换
                arr[arr.length-1-i] = temp;  // 
                //上面的只是将原结果给交换了位置,但并没有输出结果,所以还需要遍历出结果。
            }
             //遍历结果
             print(arr);
        }
        //遍历反转后的数组。
        public static void print(int[] arr){
            for (int i=0; i<arr.length; i++ ) { //int i=0表示从0开始遍历。记住 数组的属性:arr.length 数组的长度。
            //最大的索引:arr.length-1
               System.out.print(arr[i]+" ");
            }
        }
    
    }

h.
    数组的基本查表法
    class Demo9_数组_一维数组_的数组查表法 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);// in表示输入的意思。
    /*
    A:案例演示
        * 数组查表法(根据键盘录入索引,查找对应星期)
    */        
            
            System.out.println("数组查表法(根据键盘录入索引,查找对应星期)1~7的范围内");
            int num = sc.nextInt();
            //方法一
            char weeks = getWeek(num); //这里接收的类型跟方法的类型一致,因为想输出的结果是汉字。
            System.out.println("星期:"+weeks);
            
            //方法二
            System.out.println("星期:"+getWeek2(num));
        }
    
    // 方法一
        public static char getWeek(int weeki){//数据类型定义为char,是想输出的结果是汉字。
            //定义char,因为结果输出的结果也能是汉字,
            char[] week = new char[]{' ','一','二','三','四','五','六','七'}; //因为输入的结果是只能是1~7的范围,但是0对应的索引是一,1对应的索引是二,所以要在前面再加个元素即'',这样输入的数字都能够对应上星期了。
            return week[weeki];
        }
    
    // 方法二
        public static char getWeek2(int weeki){//数据类型定义为char,是想输出的结果是汉字。
            //定义char,因为结果输出的结果也能是汉字,
            char[] week = new char[]{'一','二','三','四','五','六','七'}; 
            return week[weeki-1]; //这里也可以让索引值-1,就能得到对应的星期。
        }
    
    // 方法三
        public static String getWeek2(int weeki){//参数类型定义为string,是想输出的结果是汉字即字符串。
            String[] week = new String[]{"星期一","星期二","星期三","星期四","星期五","星期六","星期天"}; 
            return week[weeki-1]; //这里也可以让索引值-1,就能得到对应的星期。
        }
    
    }



i. 
    元素出现的索引位置和总次数
    class Demo10_数组_一维数组_数组的基本查找_指定元素在索引出现的位置和总次数 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);// in表示输入的意思。
    /*
         A:案例演示
        * 数组元素查找(查找指定元素第一次在数组中出现的索引和一共出现的次数)
        
    */        
            //查找指定元素第一次在数组中出现的索引
            int[] arr = new int[]{44,6,7,8,90,4,2,8};
            Earr(arr);
             System.out.println("请从上面选择一个数进行输入");    
            //先遍历结果
            int num = sc.nextInt();
            int result = Arr(arr, num);
            System.out.println("指定元素"+num+"第一次在数组中出现的索引是:"+result);


            //查找指定元素在数组中出现的总次数    
            int sum = getIndex(arr,num);
            System.out.println("指定元素"+num+"数组中出现的总次数是:"+sum);
    
        }
        //遍历结果
        public static void Earr(int[] arr){
            for (int i=0; i<arr.length; i++ ) {
               System.out.print(arr[i]+" ");
            }
        }
    
        //查找指定元素第一次在数组中出现的索引
        public static int Arr(int[] arr, int value){
            for (int i=0; i<arr.length ; i++ ) {
                if(arr[i] == value){
                    return i;
                }
            }
            return -1;
        }


        //元素在数组中出现的总次数
        public static int getIndex(int[] arr,int value){
            int count = 0; //定义计数器,用来计算元素出现的总次数
                for (int i = 0; i<arr.length; i++ ) {
                    if(arr[i] == value){
                        count++;
                    }   
                }
                return count;
        }
    }


j.
    二维数组 
        格式:
            int[][] arr = new int[3][2]; 且索引都是从【0】开始的。
            arr[0] 表示二维数组中的第一个一维数组
            arr[0][1]表示二维数组中的第一个一维数组的第二个元素


        怎么读?        
            1)这是一个二维数组
            2)且这个二维数组中定义了3个一维数组
            3)最后这个一维数组中都有两个元素。
    
        多种格式:
            int[][] arr = new int[3][4]; 最常用。
            int[] arr[] = new int[4][5];
            int arr[][] = new int[5][7];    
            第一种最常用, new int[5][7]形式都不变。
        
        a.  常规形式
            int[][] arr = new int[3][]; 二维数组,声明三个一维数组,但都没有指定元素个数。
            arr[0] = new int[2]; 声明第一个一维数组有二个int元素
            arr[1] = new int[4]; 声明第二个一维数组有四个int元素
            arr[2] = new int[3]; 声明第三个一维数组有三个int元素
         
        b.  简写形式
            int[][] arr = {{3,5,6},{2,4},{5,5,6},{7,9,23}}; 二维数组,声明了4个一维数组。
            第一个一维数组有3个int元素
            第二个一维数组有2个int元素
            第三个一维数组有3个int元素    
            第四个一维数组有3个int元素    


​        

    注意下面定义的区别
            int x;
            int y;
            int x,y;  xy同时说明为一个int类型。
            
            int[] x;     声明一个一维数组
            int[] y[];    声明一个二维数组
            
            int[] x,y[];    x是一维数组,y是二维数组
            //可以看做: 
            //int[] x;  是一维数组
            //int[] y[] 是二维数组

例子:
​    
        案例演示
            * 定义二维数组,输出二维数组名称,一维数组名称,一个元素
        
        int[][] arr = new int[3][4]; // 定义二维数组
        System.out.println(arr);     // 输出二维数组名称 
        System.out.println(arr[2]);  // 二维数组中的第三个一维数组
        System.out.println(arr[2][1]);  // 第三个一维数组的第二个元素 
        //[[I@16d3586 二维数组的地址值
        //[I@154617c  一维数组的地址值
        //0  一维数组的第二个元素的默认值

记住: 数组是引用数据类型的,默认值是null。
​            


例子:
需求:公司年销售额求和
        某公司按照季度和月份统计的数据如下:单位(万元)
        第一季度:22,66,44
        第二季度:77,33,88
        第三季度:25,45,65
        第四季度:11,66,99


class  Demo14_数组_二维数组_公司季度销售额求和  {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);// in表示输入的意思。
/*
    需求:公司年销售额求和
        某公司按照季度和月份统计的数据如下:单位(万元)
        第一季度:22,66,44
        第二季度:77,33,88
        第三季度:25,45,65
        第四季度:11,66,99
*/        
    int[][] arr = {{22,66,44},{77,33,88},{25,45,65},{11,66,99}};

    twoArray2(arr);

    }    

    //求 总季度的总额
        public static int twoArray(int[][] arr){
            int sum =0;    //定义变量,用于记录4个季度的总额
                for (int i = 0;i<arr.length;i++ ) {
                    for (int j =0;j<arr[i].length ;j++ ) {
                        sum+=arr[i][j]; //累加
                       //System.out.print(arr[i][j]+" "); //输出总额
                    }    
                     
                }
                return sum;
        }


        //求单个季度的总额 和 总季度的和
        public static void twoArray2(int[][] arr){
        int sum =0;     //定义变量,用于记录单个季度的总额
            for (int i = 0;i<arr.length;i++ ) {
                for (int j =0;j<arr[i].length ;j++ ) {
                    if(arr[i] == arr[i]){ //如果当前一维数组 == 一维数组
                            sum+=arr[i][j];     //累加
                            System.out.print(arr[i][j]+" ");
                            
                    }        
                    else{
                        sum+=arr[i][j];
                        System.out.print(arr[i][j]+" ");
                    }
                }
                 System.out.println("每个季度的单独总额:"+sum);        
                sum=0; //每个单独的季度计算出结果后,单个额度的总额度清0
            }
                int result = twoArray(arr);
                System.out.println("4个季度的总额:"+result);    
        }




k.
思考题Java中的参数传递问题及图解

    class  Demo15_数组_思考题Java中的参数传递问题及图解{
        //看程序写结果,并画内存图解释
            public static void main(String[] args) {
                int a = 10;
                int b = 20;
            /*    
                System.out.println("a:"+a+",b:"+b);  // a=10 b=20 对
                //int是基本数据类型
                change(a,b);  //基本数据类型的值传递,不改变原值,因为调用后就会弹栈,局部变量随之消失【局部变量在栈内存】
                System.out.println("a:"+a+",b:"+b);  //a=20,b=40为什么错?正确:a=10,b=20 这里涉及方法调用完后弹栈的问题。 因为change(a,b)输出完结果后,就会被弹栈,且这句a,b的就是上面定义的值,即a=10,b=20。
            */
            
                //数组是引用数据类型
                //
                int[] arr = {1,2,3,4,5};
                change(arr);    //结果: 1    4 3 8 5        
                //引用数据类型的值传递,改变原值,因为即使方法弹栈,但是堆内存数组对象还在,可以通过【地址继续访问堆内存中的值】
                System.out.println("arr[1]的值是:"+arr[1]); //4       
            
            }
        
            public static void change(int a,int b) {
                System.out.println("a:"+a+",b:"+b); //a=10,b=20 对
                a = b;                               //a=20
                b = a + b;                            //b=40
                System.out.println("a:"+a+",b:"+b); //a=20,b=40 对
            }


            public static void change(int[] arr) {
                for(int x=0; x<arr.length; x++) {    //索引      索引对应的值        是否进入if   arr结果
                    if(arr[x]%2==0) {                // 0            1                不进        1
                        arr[x]*=2;                    // 1            2                 进        2*2=4    
                    }                                // 2            3                不进        3
                    System.out.print(arr[x]+" ");    // 3            4                 进        4*2=8
                }                                    // 4            5                不进        5
                    System.out.println();                                
            }                                        
    
    }

【注意 经典问题】
    * 基本数据类型的值传递,不改变原值,因为方法调用后会被弹栈,方法中的局部变量也跟着方法消失。【方法变量都在栈内存】
    * 引用数据类型的值传递,改变原值,因为即使方法调后会被弹栈,但堆内存中的对象或数组还存在,仍然可以通过地址值来访问堆内存中的数据。

java中是'值'传递还是'址'传递。
    说法一:都传递,因为基本数据类型传递的是值,引用数据类型传递的是地址。
    说法二:只传递值,因为地址值也是值,因为支持者是:詹姆斯·高斯林
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值