一、数组的定义和访问
数组就是一个容器,用来存一批同种类型的数据。
1.1 静态初始化数组
定义数组的时候直接给数组赋值。
1.1.1 数组定义
静态初始化数组的格式:
//完整格式
数据类型 [] 数组名 = new 数据类型[]{数据1,数据2,数据3};
eg: int[] arr = new int[]{5,3,7,8};
//简写
数据类型[] 数组名 = {元素1,元素2,元素3,......};
eg: int[] ages = {12,34,36};或 int ages[] = {12,34,36};
数组是引用类型,数组变量名中存储的是数组在内存中的地址。
1.1.2 数组访问
索引:也叫下标,是指一个数据在数组里面排第几个位置,从0开始。
数组最大索引为数组的长度-1
1.//定义数组
String[] names = {"张飞","刘备","关羽"};
2.//访问数组
//数组名可以找到数组对象的地址,再通过索引就可以定位到具体的元素了 :数组名[索引]
System.out.println(names[0]);//张飞
//下面代码没有3索引,会出现ArrayIndexOutOfBoundsException 索引越界异常
//System.out.println(names[3]);
3.//修改数组中的数据
names[0] = "赵云";
System.out.println(names[0]);//赵云
4.//获取数组长度 数组.length
System.out.println("数组长度:" + names.length);
5.//获取数组的最大索引: names.length - 1(前提是数组中存在数据)
System.out.println("最大索引是:" + (names.length - 1));
int[] arr2 = {};//空数组
System.out.println(arr2.length - 1);//-1
1.1.3 数组的遍历
所谓遍历意思就是将数组中的元素一个一个的取出来。
我们可以使用for循环从0开始一直遍历到长度-1的位置,就可以获取所有的索引了。
//定义数组
int[] arr = {1,2,3,4,5,6};
//循环遍历,获取每个数组元素
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
1.1.4 数组静态初始化案例
/*
数组遍历-求和
需求:某部门5名员工的销售额分别是:16、26、36、6、100,
请计算出他们部门的总销售额。
*/
public class Demo {
public static void main(String[] args) {
//定义数组存储某部门5名员工的销售额
int[] arr = {16,26,36,6,100};
//定义总销售额变量
int sum = 0;
//循环遍历数组,并求和
for (int i = 0; i < arr.length; i++) {
//arr[i]:每个数据(16,26,36,6,100)
System.out.print(arr[i] + " ");
sum += arr[i];
}
System.out.println();
System.out.println("他们部门的总销售额为" + sum);
}
}
1.2 动态初始化数组
定义数组时先不存入具体的元素值,只确定数组存储的数据类型和数组长度。
动态初始化数组的格式:
数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];
使用动态初始化定义数组时,根据元素类型不同,默认值也有所不同。
int[] arr = new int[5];
//默认值为0
System.out.println(arr[4]);
//动态数组赋值
arr[4] = 10;
System.out.println(arr[4]);
两种数组定义的方法各自适合什么业务场景?
-
动态初始化:适合开始不确定具体元素值,只知道元素个数的业务场景。
-
静态初始化:适合一开始就知道要存入哪些元素值的业务场景。
1.3 数组常见案例
1.3.1 评委的打分案例
/**
* 练习案例-评委打分案例
* 案例需求:
* 某歌唱比赛,需要开发一个系统:可以录入6名评委的打分,录入完毕后立即输出平均分做选手得分
*/
import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
//定义数组:动态初始化
int[] arr = new int[6];
//键盘录入评委打分
Scanner sc = new Scanner(System.in);
for (int i = 0; i < arr.length; i++) {
System.out.println("请输入" + (i+1) + "号评委的分数:");
arr[i] = sc.nextInt();
}
//计算评分总和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
//计算平均分
int avg = sum/6;
System.out.println("该选手得分为:" + avg);
}
}
1.3.2 统计及格人数
/**
* 练习案例-成绩数据分析
* 需求
* 某班级学生的Java考试成绩是:99, 100, 62, 15, 48, 65, 98, 99, 5, 59.5, 75;
* 请统计及格学生总人数。
*/
public class Demo2 {
public static void main(String[] args) {
double[] arr = {99, 100, 62, 15, 48, 65, 98, 99, 5, 59.5, 75};
//定义计数变量
int count = 0;
for (int i = 0; i < arr.length; i++) {
if(arr[i] >= 60){
count++;
}
}
System.out.println("及格人数共有:" + count + "个");
}
}
1.3.3 数组求最值
/**
* 练习案例-数组求最值
*/
public class Demo3 {
public static void main(String[] args) {
int[] arr = new int[5];
//给动态数组赋值
Scanner sc = new Scanner(System.in);
System.out.println("请输入五个整数:");
for (int i = 0; i < arr.length; i++) {
arr[i] = sc.nextInt();
}
//控制台上输出数组元素
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
//求最大值
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if(max < arr[i]){
max = arr[i];
}
}
System.out.println("数组中最大值为:" + max);
//求最小值
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if(min > arr[i]){
min = arr[i];
}
}
System.out.println("数组中最小值为:" + min);
}
}
1.3.4 数组反转
/**
* 练习案例-数组反转
* 某个数组有5个数据:10,20,30,40,50,请将这个数组中的数据进行反转。
* [10, 20, 30, 40, 50] 反转后 [50, 40, 30, 20, 10]
*
*/
public class Demo5 {
public static void main(String[] args) {
int[] arr = {10,20,30,40,50};
int i = 0;//数组第一个元素
int j = arr.length-1;//数组最后一个元素
//方法1:
//用while循环,进行数据交换
while (i<=j){
//第一个和最后一个交换,第二个和倒数第二个交换......
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
/*
方法2:
// 2、定义一个循环,设计2个变量,一个在前,一个在后
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
// arr[i] arr[j]
// 交换
// 1、定义一个临时变量记住后一个位置处的值
int temp = arr[j];
// 2、把前一个位置处的值赋值给后一个位置了
arr[j] = arr[i];
// 3、把临时变量中记住的后一个位置处的值赋值给前一个位置处
arr[i] = temp;
}
*/
//输出反转后的数组
for (int k = 0; k < arr.length; k++) {
System.out.print(arr[k] + " ");
}
}
}
1.3.5 随机排名
/**
* 练习案例-随机排名
* 某公司开发部5名开发人员,要进行项目进展汇报演讲,现在采取随机排名后进行汇报。
* 请先依次录入5名员工的工号,然后展示出一组随机的排名顺序。
*/
public class Demo6 {
public static void main(String[] args) {
int[] arr = new int[5];
Random r = new Random();
//录入员工工号,存入数组
Scanner sc = new Scanner(System.in);
for (int i = 0; i < arr.length; i++) {
System.out.println("请录入第" + (i+1) + "名员工的工号:");
int num = sc.nextInt();
arr[i] = num;
}
//数组随机打乱顺序
//1.循环获取数组的每个元素
//2.循环的时候,针对每个元素生成一个随机数(替换的位置)
//3.数据交换
for (int i = 0; i < arr.length; i++) {
int m = r.nextInt(5);
int temp = arr[i];
arr[i] = arr[m];
arr[m] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
二、数组在计算机中的执行原理
Java为了便于虚拟机执行Java程序,将虚拟机的内存划分为 方法区、栈、堆、本地方法栈、寄存器 这5块区域。
-
方法区:字节码class文件先加载到这里
-
栈:方法运行时所进入的内存区域,由于变量在方法中,所以变量也在这一块区域中
-
堆:存储new出来的东西,并分配地址。由于数组是new 出来的,所以数组也在这块区域。
下面是上面案例执行的内存原理如下图所示,按照① ② ③ ④ ⑤ ⑥ 的标记的顺序来看
总结一下int a = 10
与 int[] arr = new int[]{11,22,33}的区别
-
a是一个变量,在栈内存中,a变量中存储的数据就是10这个值。
-
arr也是一个变量,在栈中,存储的是数组对象在堆内存中的地址值
// 这里的int a是一个基本类型变量,存储的是一个数值 int a = 10 ; //这里的int[] arr是一个引用类型的变量,存储的是一个地址值 int[] arr = new int[]{44,55,66};
注意:
-
两个变量指向同一个数组时,两个变量记录的是同一个地址值。
当一个变量修改数组中的元素时,另一个变量去访问数组中的元素,元素已经被修改过了。
-
如果某个数组变量中存储的null,代表这个数组变量没有指向数组对象,需要注意可以输出这个变量,但是不能用这个数组变量去访问数据或者访问数组长度,会报空指针异常:NullPointerException。
简单说说 int a = 20; int[] arr = new int[3]这两行代码的执行原理?
答:a是变量,直接放在栈中,a变量中存储的数据就是20这个值。
new int[3]是创建一个数组对象,会在堆内存中开辟区域存储3个整数。
arr是变量,在栈中,arr中存储的是数组对象在堆内存中的地址值。
三、Debug调试工具
Debug调试工具的使用步骤如下:
1、打断点(你希望程序暂停在那一行,注意: 要打在正式的代码行) 2、使用debug运行程序 3、控制程序一步一步执行 Step Into: 下一步,如果有方法,会进入方法 Stepover: 下一步,如果有方法自动执行完成(不进入方法) 4、查看程序执行的情况 Debugger: 查看方法执行情况,查看程序中变量的变化情况 Console: 普通控制台,输入数据或者查看输出的数据 5、停止debug,取消断点