20210219Java数组

本文深入介绍了Java数组的概念、分类、使用方法,包括一维数组和二维数组的声明、初始化、元素访问、长度获取及遍历。还讨论了数组的默认初始化值,并通过实例展示了数组的内存解析。最后提供了两个数组相关的编程练习,帮助读者巩固理解。
摘要由CSDN通过智能技术生成

Java数组

编辑时间:2021/02/19

读完本节:大概花费40分钟,共3551词

1.数组(Array)
  1. 定义:数组(Array)是多个相同类型数据一定顺序排列的集合,并使用一个一个名字作为数组名,并通过编号的方式对这些数据进行统一管理。

  2. 数组常见的概念

    数组名(标识符);索引(下标);元素(每一个索引所对应的值);数组长度(数组所包含元素的个数)

  3. 数组的特点:

    1. 数组是有序排列的。
    2. 数组属于引用数据类型的变量。数组的元素既可以是基本数据类型(整型、浮点型、字符型、布尔类型)也可以是引用数据类型(类、数组、接口)。
    3. 创建数组对象会在内存中开辟一整块连续的空间。
    4. 数组的长度一旦确定,就不能修改,此时想要扩展数组的长度通常做法是重新new一个数组,然后拷贝。
  4. 数组的分类:

    按照维数:一维数组、二维数组…二维数组以上的数组统称为多维数组

    按照元素的类型:基本数据类型的数组、引用数据类型的数组

  5. 二维数组:

    对于二维数组的理解可以堪称是一位数组array1又作为另一个数组array2的元素而存在。即理解为外层数组的元素是引用数据类型,这个引用数据类型就是类array,其实从数组底层的运行机制来看,并不存在多维数组,仅仅只是一维数组的扩展使用。

2.数组的使用
  1. 一维数组的使用

    1. 一维数组的声明和初始化

      1. 数组的声明

        //一维数组的声明
        int[] id;
        
      2. 静态初始化:数组的初始化和赋值操作同时进行

        //在声明的同时可以直接初始化,也可以先声明再初始化
        //同变量相同的是无论是直接初始化,还是先声明再初始化,都需要对声明的数组进行初始化
        
        //声明的同时初始化
        int[] id1 = new int[]{1,2,3,4,5};//声明为int类型,并初始化
        
        //或先声明在初始化
        long[] id2;//声明为long类型
        id2 = new long[]{1,2,3,4};//初始化
        
      3. 动态初始化:数组的初始化和赋值操作分开进行

        //动态初始化
        
        //声明的同时初始化
        String[] str = new String[4];//声明为String类型,并初始化内存空间
        
        //或先声明在初始化
        double[] id2;//声明为double类型
        id2 = new double[4];//初始化
        
      4. 补充

        1. 常见的错误写法

          int arr1 = new int[];
          int[5] arr2 =new int[5];
          int[] arr3 = new int[3]{1,2,3};
          
        2. 不常见的正确写法

          int[] arr = {1,2,3,4};//自动将arr类型推断为int型
          
          //若先声明后初始化的化则不能省略,如下是错误的
          int[] arr;
          arr = {1,2,3,4}
          
        3. 从上述的静态初始化和动态初始化可以看出,在初始化完成之后,数组的长度就被确定了,因为不确定长度就无法在内存中开辟相应的空间进行操作。

    2. 调用一维数组的指定位置的元素

      通过索引的方式调用指定位置的元素,数组的索引是从0开始的,到数组的长度减一结束。

      //对上面定义的str数组赋值
      str[0] = "1";
      str[1] = "2";
      str[2] = "3";
      str[3] = "4";
      //str[4] = "5";//编译可通过,但运行时报数组越界的错误
      
      //输出处于第一位的元素
      System.out.print(str[0]);
      
    3. 获取一维数组的长度

      使用数组的属性:length

      System.out.print(str[].length);//4
      System.out.print(id1[]);//5
      
    4. 遍历一维数组

      通常使用for循环进行数组索引的遍历

      //遍历打印数组
      for(int i = 0;i < str[].length;i++){
          
          System.out.print(str[i]);
          
      }
      
  2. 多维数组的使用(二维举例,更高的类同)

    1. 二维数组的声明和初始化

      1. 数组的声明

        int[][] arr;
        
      2. 静态初始化

        //静态初始化
        //先声明后初始化
        int[][] arr1;
        arr1 = new int[][]{{1,2,3}{4,5,6}{7,8}};
        //声明的同时初始化
        int[][] arr2 = new int[][]{{1,2,3}{4,5,6}{7,8}};
        
      3. 动态初始化

        //动态初始化
        //先声明后初始化(略)
        //声明的同时初始化
        //动态初始化1
        int[][] arr3 = int[3][2];
        //动态初始化2
        String[][] arr4 = String[3][];
        
      4. 补充

        1. 常见的错误写法

          String[][] arr5 = new String[][5];
          String[2][3] arr6 = new String[][];
          String[][] arr7 = new String[3][2]{{1,2}{3,4}{5,6}};
          
        2. 不常见的正确写法

          int[] arr8[] = new int[][]{{1}{2,3}{4,5,6}};
          int[] arr9[] = {{1}{2,3}{4,5,6}};//类型推断
          
    2. 调用二维数组的指定位置元素

      类同一维使用索引。

      //打印输出
      System.out.print(arr1[0][0]);//打印输出arr1的第一位元素
      System.out.print("\n");
      int[][] arr2 = new int[][]{{1,2,3}{4,5,6}{7,8}};
      System.out.print(arr2[2][2]);//输出arr2的[2][2]号元素,未赋值因此是0
      
    3. 获取二维数组的长度

      使用数组的length属性

      //二维或多维元素有内层和外层之分
      
      int[][] arr2 = new int[][]{{1,2,3}{4,5,6}{7,8}};
      //打印输出二维数组外层的长度
      System.out.print(arr2.length);//3
      //打印输出二维数组的内层长度
      System.out.print(arr2[1].length);//3
      System.out.print(arr2[2].length);//2
      
    4. 遍历二维数组

      通常使用for循环的嵌套

      //遍历输出二维数组arr2
      int[][] arr2 = new int[][]{{1,2,3}{4,5,6}{7,8}};
      for(int i = 0;i < arr2.length;i++){//外层元素
          for(int j = 0;j < arr2[i].length;j++){//内层元素
      		System.out.print(arr2[i][j]);
          }
          System.out.print("\n");//控制换行
      }
      
3.数组的默认初始化值
  1. 一维数组的默认初始化值

    所有整型(byte、short、int、long)数组默认初始化值是0,浮点型(double、float)数组默认初始化值是0.0,字符型数组默认初始化值是ASCII标号为0的字符(或为\u0000,而非‘0’),引用数据类型(String)型数组默认初始化值是null(不是“null”)。布尔型数组的默认初始化值是false(在java中用0表示false用1表示true)。

    //一维数组默认初始化值输出
    public class ArrayTest{
        public static void main(String[] args){
            //使用动态初始化确保不被静态初始化所后续赋值所干扰
            int[] arr0 = new int[2];
            System.out.println(arr0[0]);//0
            
            short[] arr1 = new short[2];
            System.out.println(arr1[0]);//0
            
            byte[] arr2 = new byte[2];
            System.out.println(arr2[0]);//0
            
            long[] arr3 = new long[2];
            System.out.println(arr3[0]);//0
            
            double[] arr4 = new double[2];
            System.out.println(arr4[0]);//0.0
            
            float[] arr5 = new float[2];
            System.out.println(arr5[0]);//0.0
            
            char[] arr6 = new char[2];
            System.out.println(arr6[0]);//'/u0000'所表示的字符
            
            String[] arr7 = new String[2];
            System.out.println(arr[7]);//null
            
            boolean[] arr8 = new boolean[2];
            System.out.println(arr8[0]);//false
        }
    }
    
  2. 二维数组的默认初始化值

    对于动态初始化方式一:外层元素默认初始化值是地址值,内层元素默认初始化值与一维数组情况相同。

    对于动态初始化方式二:外层元素默认初始化值是null,内层元素默认初始化值不存在,若调用控制台报空指针异常。

    //二维数组的默认初始化值
    public class ArrayTest1{
        public static void main(String[] args){
            int[][] arr0 = new int[3][4];
            System.out.println(arr0[0]);
            //I@15db9742 I表示int型数组,@后面是数组的外层第一位元素在内存中的位置
            System.out.println(arr0[0][0]);
            //0和一维数组一样
            
            float[][] arr1 = new float[4][3];
            System.out.println(arr1[0]);
            //F@6d06d69c F表示float型数组,@后面是数组的外层第一位元素在内存中的位置
            System.out.println(arr1[0][0]);
            //0.0和一维数组一样
            
            String[][] arr2 = new String[4][3];
            System.out.println(arr2[0]);
            //Ljava.lang.String;@7852e922
            //@前表示的是类String,是引用类型的数组,@后面是数组的外层第一位元素在内存中的位置
            System.out.println(arr2[0][0]);
            //null和一维数组一样
            
            
            //二维数组的 动态初始化值2
            double[][] arr3 = new double[4][];
            System.out.println(arr3[0]);
            //null
            //原因是外层只分配了4个元素,但是内层元素内容并未给出,因此为null
            System.out.println(arr3[1][0]);
            //NullPointerExcetption空指针异常
            //原因是外层的第二个元素并没有对其再确定内层的内容,因此内存中没有其指向的地址,所以空指针
            
           
        }
    }
    
4.数组的内存解析
  1. 内存的简化结构

    image-20210221052052892

  2. 一维数组的内存解析

    此处的地址值是jvm虚拟算出的哈希值,屏蔽了底层真实的内存地址

    arr数组再内存中初始化并赋上默认初始化值

    image-20210221214617777

    arr数组更改默认初始化值为用户定义值{1,2,3}

    image-20210221214643354

    执行第二句初始化并赋上默认值

    image-20210221214943968

    arr1数组更改默认初始化值为用户定义值,这里的arr1[1]和arr1[2]存储的值应当存放再常量池中,此处为了便于演示,直接写在旁边。

    image-20210221215034110

    执行最后一句,重新为arr1分配新的内存空间

    image-20210221214751728

    随后的某一个时间点,取消连接的“地址b”在堆区因为没有在栈区找到被引用所以随后java垃圾回收机制将其自动销毁

    image-20210221214809978

    在执行完所有语句之后处于栈区的数组依次出栈,栈区清空后,堆区中开辟出的空间会在某一个时间点被java垃圾回收机制销毁

  3. 二维数组的内存解析

    arr1数组再内存中初始化并赋上默认初始化值

    image-20210221061307820

    执行第二句,将arr1[1]的值更改为用户定义值

    image-20210221061905408

    执行第三句,为arr1[2]申请新的内存空间

    image-20210221062431525

    执行最后一句,为arr1[2][1]赋上30

    image-20210221062829520

    在执行完所有语句之后处于栈区的数组依次出栈,栈区清空后,堆区中开辟出的空间会在某一个时间点被java垃圾回收机制销毁

5.练习
  1. 一维数组练习

    //从键盘读入学生成绩,找出最高分,并输出学生成绩等级
    /*
    成绩 >= 最高分-10 等级为A
    成绩 >= 最高分-20 等级为B
    成绩 >= 最高分-30 等级为C
    其余 等级为D
    */
    import java.util.Scanner;
    public class ArrayTest {
        public static void main(String[] args){
            //获取学生人数
            System.out.print("Enter student number: ");
            Scanner scan = new Scanner(System.in);
            int stuNumber = scan.nextInt();
            System.out.println("Enter " + stuNumber + " students score:");
    
            //初始化最高分
            int maxScore = 0;
    
            //创建int数组保存学生成绩
            //创建数组,动态初始化
            int[] score = new int[stuNumber];
            //给数组中的元素赋值
            for(int i = 0;i < score.length;i++){
                score[i] = scan.nextInt();
    
                //判断并比较等级,优化
                if(score[i] > maxScore){
                    maxScore = score[i];
                }
            }
            //输出最高分
            System.out.println("The highest score is: " + maxScore);
    
    //        //判断并比较等级
    //        for(int i = 0;i < score.length;i++){
    //            if(score[i] > maxScore){
    //                maxScore = score[i];
    //            }
    //        }
    
            //判断学生成绩等级并输出
            char level;
            for(int i = 0;i < score.length;i++){
                if(maxScore - score[i] <= 10){
                    level = 'A';
                }else if(maxScore - score[i] <= 20){
                    level = 'B';
                }else if(maxScore - score[i] <= 30){
                    level = 'C';
                }else{
                    level = 'D';
                }
                System.out.println("Student " + i + "score is " + score[i] + "grade is " + level);
            }
        }
    }
    
  2. 二维数组练习

    练习1:获取arr数组中的所有元素和

    j = 0j = 1j = 2j = 3
    i = 0358-
    i = 1129--
    i = 27064
    public class ArrayTest{
        public static void main(String[] args){
            int[][] arr = new int[][]{{3,5,8},{12,9},{7,0,6,4}};
    
            int sum = 0;
    
            for(int i = 0;i < arr.length;i++){
            	for(int j = 0;j < arr[i].length;j++){
                	sum += arr[i][j];
                }
            }
            System.out.println("总和为:" + sum);
        }
    }
    

    练习2:判断能否通过编译

    //声明: int[] x,y[];
    //在给x,y变量赋值以后,能够通过编译的是
    
    //分析:int[] x,y[];等价于int[] x; int[][] y;
    //所以x是int型的一维数组,y是int型的二维数组
    
    x[0] = y;
    //把二维数组赋值给一维数组的元素 false
    
    y[0] = x;
    //把一维数组赋值给二维数组的外层元素 true
    
    y[0][0] = x;
    //把一维数组赋值给二维数组的内层元素  true
    
    x[0][0] = y;
    //一维数组x没有内层元素 false
    
    y[0][0] = x[0];
    //二维数组的内层元素赋值为一维数组的元素值 true
    
    x = y;
    //一维数组赋值为二维数组 false
    

    练习3:使用二维数组打印一个10行的杨辉三角

    public class yangHui{
        public static void main(String[] args){
            /*
            * 杨辉三角:
            * 1. 第一行有一个元素,第n行有n个元素
            * 2. 每一行的第一个元素和最后一个元素都是1
            * 3. 从第三行开始,对于非第一个元素和最后一个元素有
            *    该元素 = 上一行同列元素的前一个元素 + 上一行同列元素 即:
            *    yangHui[i][j] = yangHui[i - 1][j - 1] + yangHui[i - 1][j];
            *
            * */
    
            //1. 声明并初始化二维数组
            int[][] yangHui = new int[10][];
    
            //2. 给数组元素赋值
            for(int i = 0;i < yangHui.length;i++){//外层循环遍历10行
                //每一行只有i + 1个元素,数组下标从0开始
                yangHui[i] = new int[i + 1];
    
                //给首末元素赋值
                yangHui[i][0] = yangHui[i][i] = 1;
    
                //给其余元素赋值 方法1
    //            for(int j = 0;j < yangHui[i].length;j++){//直接遍历内层元素
    //                if(yangHui[i][j] != 1){//给内层不等于1的元素重新赋值
    //                    yangHui[i][j] = yangHui[i - 1][j - 1] + yangHui[i - 1][j];
    //                }
    //            }
    
                //给其余元素赋值 方法2
              //if(i > 0) {
                //可以去掉if判断的原因是就算i = 0进到for循环中也会因为不满足for循环条件而自动结束本次i的循环
                for (int j = 1; j < yangHui[i].length - 1; j++) {//j的范围刚好排除掉了首末元素
                    yangHui[i][j] = yangHui[i - 1][j - 1] + yangHui[i - 1][j];
                }
              //}
    
            }
    
            //3. 遍历二维数组
            for(int i = 0;i < yangHui.length;i++){
                for(int j = 0;j < yangHui[i].length;j++){
                    System.out.print(yangHui[i][j] + "\t");
                }
                System.out.println();
            }
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值