# 一、数组的定义格式
# 1.1 为什么我们需要数组
例如:之前我们要存储一个分数,我们可以定义一个变量:int score = 89;现在,程序要存储、处理100个分数,我们怎样做?目前的方式:定义变量,分别存储100个分数:
缺点:
1.需要定义100个变量,名字不好起!
2.这100个变量无法遍历,如果要:求平均、求最大、求最小根本无法处理!
# 1.2 数组的概念
Java为我们提供了一种容器——数组:
它就像一所房子,里面可以有100个房间,每个房间存储一个数据,而且每个房间都会有一个“编号”。
优点:
1.不需要为每个数据定义变量。
2.可以通过下标循环遍历,很方便的访问每个元素
**什么是数组:**数组就是同一类型数据的集合,并且使用索引(下标、房间号)来访问。
数组的意义: 降低同类型的多个变量的定义以及操作的复杂度。
# 1.3 如何定义数组
第一种方式:
第二种方式
示例代码
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 如何遍历数组

示例代码
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 数组常见的错误
- 定义错误
- int[] arr = new int[]; //错误,没有长度
- int[] arr = new int[]{1,2,3,4}; //静态初始化不能指定长度
- 索引越界异常
- int[] arr = new int[3];
arr[0]=10;
arr[1]=20;
arr[2]=30;
arr[3]=40; //运行时保存,由于数组的索引值是0,1,2 。 目前你访问了3号索引
- 空指针异常
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 数组内存图
- 初步认识jvm的内存结构

- 数组的内存图

- 多个变量存储同一个数组对象
# 2.2 数组内存图的练习
- 有以下代码:
int[] arr1 = new int[3];
int[] arr2 = new int[3];
请问,在堆中产生了几个数组空间? - 有以下代码:
int[] arr1 = new int[3];
int[] arr2 = arr1;
int[] arr3 = arr2;
请问,在堆中产生了几个数组空间?有几个变量存储了这个数组空间的地址? - 有以下代码:
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 步骤分析
# 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 步骤分析
- 定义数组
- 定义一个变量count做计数器,相当于纸,存储统计结果
- 循环,从第一个人开始
if(体重 >= 130){
计数器++;
}
# 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 步骤分析
# 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 步骤分析
# 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 需求
# 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 是无效的。
请你编程实现该程序的判断。
# 4.3.2 思路分析
# 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);
}
}
