# 一、数组的定义格式

# 1.1 为什么我们需要数组

例如:之前我们要存储一个分数,我们可以定义一个变量:int score = 89;现在,程序要存储、处理100个分数,我们怎样做?目前的方式:定义变量,分别存储100个分数:
1645325786799.png
缺点:
1.需要定义100个变量,名字不好起!
2.这100个变量无法遍历,如果要:求平均、求最大、求最小根本无法处理!

# 1.2 数组的概念

Java为我们提供了一种容器——数组:
它就像一所房子,里面可以有100个房间,每个房间存储一个数据,而且每个房间都会有一个“编号”。
1645325915537.png
优点:
1.不需要为每个数据定义变量。
2.可以通过下标循环遍历,很方便的访问每个元素

**什么是数组:**数组就是同一类型数据的集合,并且使用索引(下标、房间号)来访问。
数组的意义: 降低同类型的多个变量的定义以及操作的复杂度。

# 1.3 如何定义数组

第一种方式:
1645326106424.png
第二种方式
1645326128637.png
示例代码

package _01数组的定义;

/*
数组:存储同一种类型数据的容器。

定义数组的格式:
    格式一: 动态初始化
        数据类型[]  变量名 = new  数据类型[数组的长度||数组的容量]

    格式二:静态初始化---定义与初始化是同时进行。
        数据类型[] 变量名 = new 数据类型[]{元素1,元素2....}

        数据类型[] 变量名 = {元素1,元素2....}

 */
public class Demo2 {

    public static void main(String[] args) {
        //定义一个数组长度为3的,这个数组能够存储3个元素,存储int类型的数据

        //动态初始化 ,先创建数组,然后再往数组中去存储元素。
        int[]  arr = new int[3];
        //往数组里面去存储数据
        arr[0] =10;
        arr[1]=11;
        arr[2]=12;

        //静态初始化
        int[] arr2 = {98,78,58,100};

        //存储字符串数组
        String[] arr3 = {"张三","李四","狗娃","狗剩","铁蛋"};

    }
}

# 1.4 如何遍历数组

1645328882884.png
示例代码

package _01数组的定义;

/*
目标: 遍历数组(查看数组中每一个元素)

 */
public class Demo3 {

    public static void main(String[] args) {
        //1. 动态初始化的方式创建数组
        int[] arr = new int[3]; //索引号范围:0,1,2
        arr[0] = 10;
        arr[1] = 11;
        arr[2] = 12;

        //取出数组中的所有元素, 一个个去访问,这种方式弊端很大:如果数组有10000个元素。
       //System.out.println(arr[0]);
       // System.out.println(arr[1]);
       // System.out.println(arr[2]);
       //访问数组的长度的属性: 数组的变量名.length
        System.out.println("arr1的长度:"+ arr.length);

       //for循环遍历数组的每一个元素
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

# 1.5 数组常见的错误

  1. 定义错误
  • int[] arr = new int[];  //错误,没有长度
  • int[] arr = new int[]{1,2,3,4};  //静态初始化不能指定长度
  1. 索引越界异常
  • int[] arr = new int[3];
    arr[0]=10;
    arr[1]=20;
    arr[2]=30;
    arr[3]=40; //运行时保存,由于数组的索引值是0,1,2 。 目前你访问了3号索引
  1. 空指针异常

int[] arr = null;
    arr[0] = 10;  //编译通过,运行时报错,NullPointerException();

package _01数组的定义;

/*
数组操作常见的错误:
    1. 定义语法错误。
           a,如果是动态初始化的时候是一定要指定长度。
           b.如果是静态初始化是不需要指定的长度的。
           c.访问数组的元素的时候不需要使用. 格式: 数组变量名[索引值]
    2. 索引越界异常

    3. 空指针异常
 */
public class Demo4 {

    public static void main(String[] args) {
        //如果是动态初始化的时候是一定要指定长度。
        int[] arr = new int[3];
        //静态初始化是不能指定长度的,只能指定数组存储的数据。
        int[] arr2 = new int[]{12,10,9};
        System.out.println(arr2[2]);


        //3. 索引越界
        String[] arr3 = {"狗娃","狗剩","铁蛋","如花","旺财","富贵"}; //这个数组的索引号范围:0~5
        System.out.println(arr3[5]); //6号索引是不存在的,所以一旦访问就会出现报错(下标约束越界)


        //4. 空指针异常
        char[] arr4=  null; //new char[3];  // char[] arr4 定义变量  new char[3] 创建数组对象
    
        System.out.println("arr4数组的长度:"+arr4.length);
    }
}

# 1.6 数组定义示例

package _01数组的定义;

public class Demo5 {

    public static void main(String[] args) {
        //1. Stirng类型数组存储  ctrl+R 快速替换全部,但是与内网通有热键冲突
        String[] arr1 ={"杨幂","刘恺威","古力娜扎","柳岩","郭德纲" };
        //遍历元素
        for (int i = 0; i < arr1.length; i++) {
            System.out.print(arr1[i]+",");
        }

        //换行
        System.out.println();
        //2. 使用char类型数组存储
        char[] arr2 = {'男','女','男','女','男'};
        for (int i = 0; i < arr2.length; i++) {
            System.out.print(arr2[i]+",");
        }

        System.out.println();

        //使用double类型数组存储
        double[] arr3 = {1.65,1.85, 1.70, 1.68,1.85};
        for (int i = 0; i < arr3.length; i++) {
            System.out.print(arr3[i]+",");
        }
    }
}

# 二、数组的内存图解

# 2.1 数组内存图

  1. 初步认识jvm的内存结构

1645351473109.png

  1. 数组的内存图

1645351624075.png

  1. 多个变量存储同一个数组对象

1645351674154.png

# 2.2 数组内存图的练习

  1. 有以下代码:
    int[] arr1 = new int[3];
    int[] arr2 = new int[3];
    请问,在堆中产生了几个数组空间?
  2. 有以下代码:
    int[] arr1 = new int[3];
    int[] arr2 = arr1;
    int[] arr3 = arr2;
    请问,在堆中产生了几个数组空间?有几个变量存储了这个数组空间的地址?
  3. 有以下代码:
    int[] arr1 = new int[3];
    int[] arr2 = arr1;
    arr1 = null;
    arr2[0] = 10;
    System.out.println(arr1[0]);
    请问,打印结果是什么?

# 2.3 小结

1.JVM内存的几个存储空间:
1).栈:方法被执行时入栈,方法中所有的代码都在栈中运行;
2).堆:new关键字创建的对象空间
3).方法区:存储程序运行时,使用过的“类”信息。
4).寄存器:存储即将交给CPU执行的指令
5).本次方法区:存储native修饰的方法。
2.当我们new一个数组时:int[] arr = new int[3];
1).数组空间存储在“堆”中;
2).变量arr存储在“栈”中,并且存储的是数组“堆”中的地址
3.一种类型的数组空间的地址,可以被复制任意多,但只能存储给同类型数组变量:
例如:int[] arr = new int[3];
    int[] arr1 = arr;//OK的
    double[] arr2 = arr;//编译错误,类型不同

# 三、数组常见的操作

# 3.1 案例一: 筛选数据

# 3.1.1 需求

有以下数组,存储了6名学员的体重:
int[]   arr  = {120,130,110,125,128,164};
请编程计算并打印:大于等于130斤以上的体重值。

# 3.1.2  步骤分析

1.定义需要计算的数组
2.遍历数组,获取每个元素:int n = arr[i];
3.判断元素值是否>=130:
    是:打印
4.循环结束

# 3.1.3 案例实现

package _03数组常见的操作;

/*
需求:
    存在该数组,int[] arr = {120,130,110,125,128,164},从数组中查找
    大于等于130斤的人。
 */
public class Demo1 {

    public static void main(String[] args) {
        //1. 定义一个数组存储指定的数据
        int[] arr = {120,130,110,125,128,164};
        //2. 遍历数组,取出数组的每一个元素
        for (int i = 0; i < arr.length; i++) {
            //判断当前的数据是否大于等于130
            if(arr[i]>=130){
                System.out.print(arr[i]+",");
            }

        }

    }
}

# 3.2 案例二:求和

# 3.2.1 需求

有以下数组,存储了6名学员的体重:
int[]  arr= {120,130,110,125,128,164};
请编程计算并打印这6名学员的总体重。
请编程计算并打印:大于等于130斤以上的体重值。

# 3.2.2  步骤分析

1.定义需要计算的数组
2.定义一个变量,来存储累加和
3.遍历数组,获取每个元素
4.将每个元素累加到之前定义的变量中
5.循环结束,打印存储累加和的变量

# 3.2.3 案例实现

package _03数组常见的操作;

/*
需求:
    存在该数组,int[] arr = {120,130,110,125,128,164},
    把数组的所有元素累加起来,求总和
 */
public class Demo2 {

    public static void main(String[] args) {
        //1. 定义一个数组存储指定的数据
        int[] arr = {120,130,110,125,128,164};
        //2. 定义一个变量保存每次相加的结果。
        int sum =0;
        //3. 遍历数组,的每一个元素都累加到sum变量中
        for (int i = 0; i < arr.length; i++) {
            sum+=arr[i];
        }
        System.out.println("总和是:"+sum);

    }
}

# 3.3 案例三:求平均值

# 3.3.1 需求

有以下数组,存储了6名学员的体重:
int[]  arr = {120,130,110,125,128,164};
请编程计算并打印这6名学员的平均体重。

# 3.3.2  步骤分析

1.定义需要计算的数组
2.定义一个变量,来存储累加和
3.遍历数组,获取每个元素
4.将每个元素累加到之前定义的变量中
5.循环结束
6.计算元素的平均值并存储
7.打印平均值

# 3.3.3 案例实现

package _03数组常见的操作;

/*
需求:
    存在该数组,int[] arr = {120,130,110,125,128,164},
    把数组的所有元素累加起来,求平均值
 */
public class Demo3 {

    public static void main(String[] args) {
        //1. 定义一个数组存储指定的数据
        int[] arr = {120,130,110,125,128,164};
        //2. 定义一个变量保存每次相加的结果。
        int sum =0;
        //3. 遍历数组,的每一个元素都累加到sum变量中
        for (int i = 0; i < arr.length; i++) {
            sum+=arr[i];
        }
        System.out.println("平均值:"+sum/arr.length);

    }
}

# 3.4 案例四:求最大值

# 3.4.1 需求

有以下数组,存储了6名学员的体重:
有以下数组,存储了6名学员的体重:
int[] arr  = {120,130,110,125,128,164};
请编程计算并打印这6名学员的最大体重。

# 3.4.2  步骤分析

1645946362382.png

# 3.4.3 案例实现

package _03数组常见的操作;

/*
需求:
    存在该数组,int[] arr = {120,130,110,125,128,164},
    求出数组的最大值
 */
public class Demo4 {

    public static void main(String[] args) {
        //1. 定义一个数组存储指定的数据
        int[] arr = {120,130,110,125,128,164};
        //定义一个变量记录最大值,假设第0个元素值是最大
        int max = arr[0];
        //2. 遍历数组,让数组的每一个元素都与max变量进行比较,一旦
        //发现比max变量还大的值就记录当前元素的值
        for(int i = 0 ; i<arr.length ; i++){
            if(arr[i]>max){
                max = arr[i];
            }
        }
        System.out.println("最大值:"+max);


    }
}

# 3.5 案例五:统计

# 3.5.1 需求

有以下数组,存储了6名学员的体重:
有以下数组,存储了6名学员的体重:
int[] arr  = {120,130,110,125,128,164};
请编程计算并打印:大于、等于130的元素的个数

# 3.5.2  步骤分析

  1. 定义数组
  2. 定义一个变量count做计数器,相当于纸,存储统计结果
  3. 循环,从第一个人开始

if(体重 >= 130){

计数器++;

}

  1. 循环结束
  2. 打印纸上最后记录个数

# 3.5.3 案例实现

package _03数组常见的操作;

public class Demo5 {

    public static void main(String[] args) {
//        1.定义数组
        int[] arr = {120,130,110,125,128,164};
//        2.定义一个变量count做计数器,相当于纸,存储统计结果
        int count=0;
//        3.循环,从第一个人开始
        for (int i = 0; i < arr.length ; i++) {
            if(arr[i]>=130){
                count++;
            }
        }
//        4.循环结束

//        5.打印纸上最后记录个数
        System.out.println("大于130的个数:"+ count);

    }
}

# 3.6 案例六:从控制台接收数据

# 3.6.1 需求

有以下数组:int[] arr = new int[5];请编程从控制台接收5名学员的年龄,并存储到数组中。
遍历数组,打印每个年龄值。

# 3.6.2  步骤分析

  1. 定义数组,int[] arr= new int[5];
  2. 定义一个Random对象,用于从控制台接收数据;
  3. 遍历数组,用i做索引
  4. 循环结束
  5. 遍历数组,打印每个年龄

# 3.6.3 案例实现

package _03数组常见的操作;

import java.util.Scanner;

/*
需求: 有以下数组:int[] arr = new int[5];请编程从控制台接收5名学员的年龄,并存储到数组中。
遍历数组,打印每个年龄值。

 */
public class Demo6 {

    public static void main(String[] args) {
        //1. 定一个长度为5的数组
        int[] arr = new int[5];
        //2.提示用户录入5名学员的年龄,并且存储到数组中
        Scanner sc = new Scanner(System.in);

        for (int i = 0; i <5 ; i++) {
            System.out.println("请输入第"+(i+1)+"位学员的年龄");
            int age  = sc.nextInt();
            arr[i]=age;
        }


        //3.遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+",");
        }
    }
}

# 3.7 案例七:

# 3.7.1 需求

有以下数组:int[] arr = new int[5];请编程随机生成5个1—100的整数,并存储到数组中。遍历数组,打印每个值。

# 3.7.2  步骤分析

  1. 定义一个长度为5的数组
  2. 随机产生5个随机数,并且存储到数组中

# 3.7.3 案例实现

package _03数组常见的操作;

import java.util.Random;

/*
需求:
有以下数组:int[] arr = new int[5];请编程随机生成5个1—100的整数,并存储到数组中。
遍历数组,打印每个值。

 */
public class Demo7 {

    public static void main(String[] args) {
        //1. 定义一个长度为5的数组
        int[] arr = new int[5];

        //2. 随机产生5个随机数,并且存储到数组中
        Random r = new Random();
        for (int i = 0; i < 5; i++) {
            int num = r.nextInt(100)+1;//
            arr[i] = num;
        }

        //3.遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+",");
        }


    }
}

# 3.8 学生练习1

# 3.8.1 需求

1). 定义一个5个长度的整数数组;
2). 从控制台接收5名学员的年龄,存储到数组中;
3). 遍历数组,求出平均年龄,并打印结果

# 3.8.2 案例实现

package _03数组常见的操作;

import java.util.Scanner;

public class Demo9 {

    public static void main(String[] args) {
//        1). 定义一个5个长度的整数数组;
        int[] arr = new int[5];
//        2). 从控制台接收5名学员的年龄,存储到数组中;
        Scanner scanner = new Scanner(System.in);
        for (int i = 0; i <5 ; i++) {
            System.out.println("请输入"+(i+1)+"学员年龄");
            arr[i] = scanner.nextInt();
        }
//        3). 遍历数组,求出平均年龄,并打印结果
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+",");
        }

    }
}

# 3.9 学生练习2

# 3.9.1 需求

1). 定义一个5个长度的小数数组;
2). 从控制台接收5名学员的身高,存储到数组中;
3). 遍历数组
      打印大于170的身高
      求出最大值
4).并打印:最大值

# 3.9.2 案例实现

package _03数组常见的操作;

import java.util.Scanner;

public class Demo10 {

    public static void main(String[] args) {
//        1). 定义一个5个长度的小数数组;
        int[] arr = new int[5];
//        2). 从控制台接收5名学员的身高,存储到数组中;
        Scanner scanner = new Scanner(System.in);
        for (int i = 0; i <5 ; i++) {
            arr[i] = scanner.nextInt();
        }
//        3). 遍历数组
        int max = arr[0]; //假设第一个最高
        for (int i = 0; i < arr.length; i++) {
            int height = arr[i];
            //打印大于170的身高
            if(height>170){
                System.out.print(height+",");
            }
            if(max<height){
                max = height;
            }
        }
//        4).并打印:最大值
        //换行
        System.out.println();
        System.out.println("最大值:"+max);


    }
}

# 四、综合案例

# 4.1 成绩分析系统

# 4.1.1 需求

以一个班级10个同学的数学成绩为例,进行统计。求这个班级的数学平均成绩,最高分,最低分。

# 4.1.2 思路分析

1、定义一个数组,对这10个同学的数学成绩进行保存
2、因为是10个学生的成绩,可以考虑使用循环来不断访问每个学生的成绩
3、同时定义一个变量不断累加每个学生的成绩,定义一个变量记录最大值、最小值
4、求平均成绩,只需要将总成绩/总人数就可以了
5、输出平均成绩

# 4.1.3 思路分析

package _04综合案例;

import java.util.Scanner;

/*
需求: 现以一个班级10个同学的数学成绩为例,进行统计。求这个班级的数学平均成绩,最高分,最低分。

 */
public class HomeWork1 {

    public static void main(String[] args) {
//        1、定义一个数组,对这10个同学的数学成绩进行保存
        int[] arr = new int[10];
//        2、因为是10个学生的成绩,可以考虑使用循环来不断访问每个学生的成绩
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < 10; i++) {
            System.out.println("请输入第"+(i+1)+"位同学成绩");
            int num = sc.nextInt(); //用户录入的成绩存储到num变量中
            arr[i]=num;
        }
//        3、同时定义一个变量不断累加每个学生的成绩
        int sum=0;
        //求出最大值
        int max = arr[0];

        //求出最小值
        int min = arr[0];
        for (int i = 0; i <arr.length ; i++) {
            //求和
            sum+=arr[i];

            //查找最大值的
            if(arr[i]>max){
                max = arr[i];
            }

            //查找最小值
            if(arr[i]<min){
                min = arr[i];
            }
        }

//        4、求平均成绩,只需要将总成绩/总人数就可以了
        System.out.println("平均分:"+(sum/arr.length));
        System.out.println("最大值:"+max);
        System.out.println("最小值:"+min);

    }
}

# 4.2 双色球开奖核心算法

# 4.2.1 需求

1645371120068.png
1645371135285.png

# 4.2.2 思路分析

1、定义一个数组,用于保存6个红球的中奖数字
2、使用Random来生成1-33的随机整数代表红球,共需要生成6个整数,代表6个红球
3、同时使用Random来生成1-16的随机整数代表蓝球,需要生成1个整数,代表1个蓝球,可以用一个整型变量来存储
4、输出6个红球,1个蓝球,即代表本期中奖号码

# 4.2.3 思路分析

package _04综合案例;

import java.util.Random;

/*
需求:
    1、出奖号码由6个红球 + 1蓝球组成
    2、每个红球是1—33之间的一个数字
    3、蓝球是1—16之间的一个数字
    4、本题目咱时不考虑:重复、红球排序的问题


 */
public class HomeWork2 {


    public static void main(String[] args) {
//        1、定义一个数组,用于保存6个红球的中奖数字
        int[] redArray = new int[6];
//        2、使用Random来生成1-33的随机整数代表红球,共需要生成6个整数,代表6个红球
        Random r = new Random();
        for (int i = 0; i <6 ; i++) {
            //随机产生一个红球的数字
            int redNum = r.nextInt(33)+1;
            redArray[i] = redNum;
        }

//        3、同时使用Random来生成1-16的随机整数代表蓝球,需要生成1个整数,代表1个蓝球,可以用一个整型变量来存储
        int blueNum = r.nextInt(16)+1;
//        4、输出6个红球,1个蓝球,即代表本期中奖号码
        System.out.println("本次的开奖号码:");
        for (int i = 0; i < redArray.length; i++) {
            //输出红球
            System.out.print(redArray[i]+",");
        }
        //输出蓝球
        System.out.print(blueNum);

    }
}

# 4.3 盗墓解密程序

# 4.3.1 需求

有一个古老的国王墓地,谁能找到解密程序就将能打开墓室大门;两个小偷在找到墓地后于是就开始研究规则
规则为:一串数字无论正着读还是反着读都是一样的。如:1234321 是有效的;345643 是无效的。
请你编程实现该程序的判断。
1645371473195.png

# 4.3.2 思路分析1645962191513.png

# 4.3.3 思路分析

package _04综合案例;

public class HomeWork3 {

    public static void main(String[] args) {
        //1. 定义一个数组,并且存储数据
        int[] arr = {1,2,3,4,1};
        //2. 定义两个变量记录要对元素的索引值
        int startIndex = 0;
        int endIndex = arr.length-1;

        //变量是用于记录是否破解成功,true表示破解成功,false表示破解失败
        boolean flag = true; //默认破解成功的。
        //3. 循环对比两个数是否一致
        while(startIndex<endIndex){
            if(arr[startIndex]!=arr[endIndex]){
                flag=false;
                //结束循环
                break;
            }
            //每对比完一次,开始索引值都应该+1 , 结束索引值都应该-1
            startIndex++;
            endIndex--;
        }
        System.out.println("破解成功吗?"+flag);

    }
}