day05_java数组

容器的概念

变量中只能存储一个数据,新的数据进来,老的数据将被替换,如果需要存储多个数据,需要使用容器。容器:是将多个数据存储到一起,每个数据称为该容器的元素。生活中的容器:水杯,衣柜,鞋柜,教室

数组概述

java中的数组就是一个容器,可以存储多个数据,但是数据的类型必须一致。特点如下:

  • 可以存储多个数据
  • 多个数据的类型必须保持一致
  • 数组一旦创建,长度是永远不可以发生改变

数组的声明

  • 格式一:数据类型[ ] 数组名字;
  • 格式二:数据类型 数组名称[ ];
示例
package demo1;

public class Test {
    public static void main(String[] args) {
        //(1)定义一个存储int类型数组的变量arrayA
        //int类型数组: 该容器中只能存储的是int类型的数字
        int[] arrayA;
        //System.out.println(arrayA);//错误的: arrayA只是一个用来存储数组的变量,但是目前没有向arrayA中存储数组

        //(2)定义一个存储double类型数组的变量arrayB
        //double类型数组: 该数组容器中只能存储double类型的数据
        double arrayB[];

        //(3)定义一个存储char类型数组的变量arrayC
        //char类型数组: 该数组容器中只能存储char类型的数据
        char[] arrayC;

    }
}

注意事项:声明了数组,没有进行初始化是无法进行使用的

数组的初始化

方式一: 数组动态初始化,只给定数组的长度,由系统给出默认初始化值。
  • 格式:数据类型[ ] 数组名称 = new 数据类型[长度];
数组定义格式详解:
  • 左侧数据类型: 规定了数组中可以存储哪种类型的数据
  • 左侧[ ]:表示数组的意思
  • 数组名称: 就是给数组起个名字(相当于门牌号),方便找到并使用数组
  •  =:表示赋值,把具体的=右边new出来的数组容器,存储到=左边的数组变量中,但是存储的是数组在内存空间的地址值
  • new: 创建数组容器的过程
  • 右侧数据类型:和左侧保持一致
  • 右侧[]中长度:是一个int数字,表示数组中可以存储数据的数量,也叫作数组长度
代码示例
public class Demo {
    public static void main(String[] args) {
        //(1)创建一个int类型的数组,可以存储3个int数据,给该数组起个名称叫做arrayA
        int[] arrayA = new int[3];

        //(2)创建一个double类型的数组,可以存储7个double数据,给该数组起个名称叫做arrayB
        double[] arrayB = new double[7];

        //(3)创建一个char类型的数组,可以存储5个char数据,给该数组起个名称叫做arrayC
        char[] arrayC = new char[5];
    }
}
      

方式二:数组静态初始化,在创建数组时,直接确定数组元素

  • 标准格式:数据类型[ ] 数组名称 = new 数据类型[ ]{元素1,元素2,元素3,...元素n};

注意:

  • 右侧[ ]中不能写长度,JVM会根据{ }中元素的数量计算/推导出数组的长度。只要右侧[ ]中写长度,就会报错
  • { }中的每个元素之间有逗号(英文状态)隔开,最后一个元素后面没有逗号

代码示例

public class Demo {
    public static void main(String[] args) {
        //(1)创建一个int类型的数组,可以存储多个int数据100,200,300,给该数组起个名称叫做arrayA
        int[] arrayA = new int[]{100,200,300};

        //(2)创建一个double类型的数组,可以存储多个double数据1.1,2.2,3.3,4.4,5.5,6.6,7.7,给该数组起个名称叫做arrayB
        double[] arrayB = new double[]{1.1,2.2,3.3,4.4,5.5,6.6,7.7};

        //(3)创建一个char类型的数组,可以存储多个char数据'真','的','好','想','你',给该数组起个名称叫做arrayC
        char[] arrayC = new char[]{'真','的','好','想','你'};

    }
}     
      

省略格式:数据类型[ ] 数组名称 = {元素1,元素2,元素3,...元素n};

        //(1)创建一个int类型的数组,可以存储多个int数据100,200,300,给该数组起个名称叫做arrayA
        int[] arrayA = {100,200,300};

        //(2)创建一个double类型的数组,可以存储多个double数据1.1,2.2,3.3,4.4,5.5,6.6,7.7,给该数组起个名    称叫做arrayB
        double[] arrayB = {1.1,2.2,3.3,4.4,5.5,6.6,7.7};

        //(3)创建一个char类型的数组,可以存储多个char数据'真','的','好','想','你',给该数组起个名称叫做arrayC
        char[] arrayC = {'真','的','好','想','你'};

注意:

  • 省略格式右侧不用写长度,JVM根据{ }中数组元素的数量推导长度
  • 虽然没有写new,底层仍然有new的过程
  • 动态初始化和标准格式的静态初始化,可以分两步完成
  • 简化格式静态初始化,不能分成两步完成

代码示例

  public static void main(String[] args) {
        //定义数组变量,未赋值
        int[] arr;
        arr = new int[3];//动态初始化指定数组长度
        arr = new int[]{10, 20, 30};//标准格式静态初始化

        System.out.println("-------------------");
        int[] arr2;
        //arr2 = {100,200,300};//错误: 简化格式静态初始化,不能分成两步完成

    }

数组使用的前置知识

  • 数组的长度属性: 每个数组都具有长度,而且是固定的,Java中赋予了数组的一个属性,可以获取到数组的长度,语 句为: 数组名.length ,属性length的执行结果是数组的长度,int类型结果。由次可以推断出,数组的最大索引值为 数组名.length-1
  • 数组名称: 代表数组在内存空间的地址值,是一个十六进制的整数数字
  • 索引: 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。该编号从0开始到最大值(数组长度 减 1),格式:数组名称[索引编号]
  • 为数组中的元素赋值:数组名[索引] = 数值
  • 获取出数组中的元素:变量 数组名[索引]

 数组元素有默认值

在java中,如果为数组分配了内存空间,那么系统会为数组元素指定默认值,该默认值与数组的数据类型有关。

数组操作的常见问题之越界异常

观察一下代码,运行后会出现什么结果
package demo1;

public class Test {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        System.out.println(arr[3]);
    }
}

创建数组,赋值3个元素,数组的索引就是012,没有3索引,因此我们不能访问数组中不存在的索引,程序运行后,将 会抛出 ArrayIndexOutOfBoundsException 数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码

数组操作的常见问题之空指针异常
package demo1;

public class Test {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        arr = null;
        System.out.println(arr[0]);
    }
}
arr = null 这行代码,意味着变量 arr 将不会在保存数组的内存地址,也就不允许再操作数组了,因此运行的时候会抛出 NullPointerException 空指针异常。在开发中,数组的越界异常是 不能出现 的,一旦出现了,就必须要修改我们编写的 代码。

数组原理内存图

内存概述

内存是计算机中的重要原件,临时存储区域,作用是运行程序。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。 Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。
为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

JVM的内存划分:

一个数组内存图

查看下面代码
package demo1;

public class Test {
    public static void main(String[] args) {
        int[] arr = new int[3];
        System.out.println(arr);//[I@5f150435
    }
}
以上方法执行,输出的结果是 [I@5f150435 ,这个是什么呢?是数组在内存中的地址。 new 出来的内容,都是在堆内存中存储的,而方法中的变量arr 保存的是数组的地址。 输出 arr[0] ,就会输出 arr 保存的内存地址中数组中 0 索引上的元素

结论:

  • 数组名称保存数组在堆内存中的地址值
  • 通过数组名称找到堆内存中的具体数组,然后通过索引编号找到对应的具体的某个元素

 两个数组内存图

查看下面代码

package demo1;

public class Test {
    public static void main(String[] args) {
        int[] arr = new int[3];
        int[] arr2 = new int[2];
        System.out.println(arr);
        System.out.println(arr2);
    }
}

图解

结论:

每个数组都有自己独立的内存空间,互不影响,互不干扰

两个变量指向一个数组

查看下面代码

package demo1;

public class Test {
    public static void main(String[] args) {
        // 定义数组,存储3个元素
        int[] arr = new int[3]; //数组索引进行赋值 
        arr[0] = 5;
        arr[1] = 6;
        arr[2] = 7; //输出3个索引上的元素值
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);
        //定义数组变量arr2,将arr的地址赋值给arr2 
        int[] arr2 = arr;
        arr2[1] = 9;
        System.out.println(arr[1]);
    }
}

图解

结论:

  • 数组名称保存数组在堆内存空间的地址值
  • 使用数组名进行赋值时,传递的是地址值
  • 使用数组名作为方法参数和返回值,传递的都是地址值

数组练习

数组遍历: 就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石。
package demo1;

public class Test {
    public static void main(String[] args) {
        int[] arr = {11, 22, 33, 44, 55};
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

综合练习 

import java.util.Scanner;

public class Test5Array {
    /*
        需求:在编程竞赛中,有6个评委为参赛的选手打分,分数为0-100的整数分。
                选手的最后得分为:去掉一个最高分和一个最低分后 的4个评委平均值 (不考虑小数部分)。

        思路:
            1.定义一个数组,用动态初始化完成数组元素的初始化,长度为6
            2.键盘录入评委分数
            3.由于是6个评委打分,所以,接收评委分数的操作,用循环
            4.求出数组最大值
            5.求出数组最小值
            6.求出数组总和
            7.按照计算规则进行计算得到平均分
            8.输出平均分

     */
    public static void main(String[] args) {
        // 1.定义一个数组,用动态初始化完成数组元素的初始化,长度为6
        int[] arr = new int[6];
        // 2.键盘录入评委分数
        Scanner sc = new Scanner(System.in);
        //  3.由于是6个评委打分,所以,接收评委分数的操作,用循环
        for (int i = 0; i < arr.length; i++) {
            System.out.println("请输入第" + (i+1) + "个评委的打分:");
            int score = sc.nextInt();
            if(score >= 0 && score <= 100){
                // 合法的分值
                arr[i] = score;
            }else{
                // 非法的分值
                System.out.println("您的打分输入有误, 请检查是否是0-100之间的");
                i--;
            }
        }

        // 4.求出数组最大值
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if(max < arr[i]){
                max = arr[i];
            }
        }

        // 5.求出数组最小值
        int min = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if(min > arr[i]){
                min = arr[i];
            }
        }

        // 6.求出数组总和
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }

        // 7.按照计算规则进行计算得到平均分
        int avg = (sum - max - min ) / 4;

        // 8.输出平均分
        System.out.println(avg);
    }
}

二维数组

二维数组也是一种容器,不同于一维数组,该容器存储的都是一维数组容器

动态初始化格式:数据类型[ ][ ] 变量名 = new 数据类型[m][n];

示例

public class Demo {
    /*
        动态初始化格式:

            数据类型[][] 变量名 = new 数据类型[m][n];
            m表示这个二维数组,可以存放多少个一维数组
            n表示每一个一维数组,可以存放多少个元素
     */
    public static void main(String[] args) {
        // 数据类型[][] 变量名 = new 数据类型[m][n];
        int[][] arr = new int[3][3];
        /*
            [[I@10f87f48

            @ : 分隔符
            10f87f48 : 十六进制内存地址
            I : 数组中存储的数据类型
            [[ : 几个中括号就代表的是几维数组
         */
        System.out.println(arr);

        /*
            二维数组存储一维数组的时候, 存储的是一维数组的内存地址
         */
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);

        System.out.println(arr[0][0]);
        System.out.println(arr[1][1]);
        System.out.println(arr[2][2]);

        // 向二维数组中存储元素
        arr[0][0] = 11;
        arr[0][1] = 22;
        arr[0][2] = 33;

        arr[1][0] = 11;
        arr[1][1] = 22;
        arr[1][2] = 33;

        arr[2][0] = 11;
        arr[2][1] = 22;
        arr[2][2] = 33;

        // 从二维数组中取出元素并打印
        System.out.println(arr[0][0]);
        System.out.println(arr[0][1]);
        System.out.println(arr[0][2]);
        System.out.println(arr[1][0]);
        System.out.println(arr[1][1]);
        System.out.println(arr[1][2]);
        System.out.println(arr[2][0]);
        System.out.println(arr[2][1]);
        System.out.println(arr[2][2]);
    }
}

二维数组中存储的是一维数组,可以存入 提前创建好的一维数组

public class Demo {
    /*
        问题: 二维数组中存储的是一维数组, 那能不能存入 [提前创建好的一维数组] 呢 ?
        答 : 可以的
     */
    public static void main(String[] args) {
        int[] arr1 = {11, 22, 33};
        int[] arr2 = {44, 55, 66};
        int[] arr3 = {77, 88, 99, 100};

        int[][] arr = new int[3][3];

        arr[2][3] = 100;

        arr[0] = arr1;
        arr[1] = arr2;
        arr[2] = arr3;

        System.out.println(arr[1][2]);
        System.out.println(arr[2][3]);
    }
}

二维数组静态初始化

  • 完整格式 : 数据类型 变量名 = new 数据类型{ {元素1, 元素2...} , {元素1, 元素2...}
  • 简化格式 : 数据类型 变量名 = { {元素1, 元素2...} , {元素1, 元素2...} ...};

示例代码

public class Demo {
    /*
        完整格式:数据类型[][] 变量名 = new 数据类型[][]{ {元素1, 元素2...} , {元素1, 元素2...} ...};

        简化格式: 数据类型[][] 变量名 = { {元素1, 元素2...} , {元素1, 元素2...} ...};
     */
    public static void main(String[] args) {
        int[] arr1 = {11,22,33};
        int[] arr2 = {44,55,66};

        int[][] arr = {
    
    {11,22,33}, {44,55,66}};
        System.out.println(arr[0][2]);

        int[][] array = {arr1,arr2};
        System.out.println(array[0][2]);
    }
}

二维数组遍历

public class Demo {
    /*
        需求:

            已知一个二维数组 arr = {
    
    {11, 22, 33}, {33, 44, 55}};
            遍历该数组,取出所有元素并打印

        步骤:
            1. 遍历二维数组,取出里面每一个一维数组
            2. 在遍历的过程中,对每一个一维数组继续完成遍历,获取内部存储的每一个元素
     */
    public static void main(String[] args) {
        int[][] arr = {
    
    {11, 22, 33}, {33, 44, 55}};

        // 1. 遍历二维数组,取出里面每一个一维数组
        for (int i = 0; i < arr.length; i++) {
            //System.out.println(arr[i]);
            // 2. 在遍历的过程中,对每一个一维数组继续完成遍历,获取内部存储的每一个元素
            //int[] temp = arr[i];
            for (int j = 0; j < arr[i].length; j++) {
                System.out.println(arr[i][j]);
            }
        }
    }
}

二维数组求和

public class Demo {
    /*
       需求:
           某公司季度和月份统计的数据如下:单位(万元)
           第一季度:22,66,44
           第二季度:77,33,88
           第三季度:25,45,65
           第四季度:11,66,99

       步骤:
           1. 定义求和变量,准备记录最终累加结果
           2. 使用二维数组来存储数据,每个季度是一个一维数组,再将4个一维数组装起来
           3. 遍历二维数组,获取所有元素,累加求和
           4. 输出最终结果
    */
    public static void main(String[] args) {
        // 1. 定义求和变量,准备记录最终累加结果
        int sum = 0;
        // 2. 使用二维数组来存储数据,每个季度是一个一维数组,再将4个一维数组装起来
        int[][] arr = {
    
    {22, 66, 44}, {77, 33, 88}, {25, 45, 65}, {11, 66, 99}};
        // 3. 遍历二维数组,获取所有元素,累加求和
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                sum += arr[i][j];
            }
        }
        // 4. 输出最终结果
        System.out.println(sum);
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44462792/article/details/121689970