3.数组
3.1什么是数组
数组就是存储数据长度固定的容器,存储多个数据的数据类型要一致。
3.2数组定义格式
3.2.1第一种(常用)
数据类型[] 数组名
示例:
int[] arr; double[] arr; char[] arr;
3.2.2第二种(在C语言的格式)
数据类型 数组名[]
示例:
int arr[]; double arr[]; char arr[];
在学习C语言的时候我们只能用第二种,如下图所示,因此大家也习惯比较使用第二种格式,但是学习java语言有必要知道,这两种都用的多。
3.3数组静态初始化
3.3.1什么是静态初始化
在创建数组时,直接将元素确定,坦白地说就是知道每个元素的值。
3.3.2静态初始化格式
-
完整版格式
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...}; 举例: int[] arr = new int[]{1,2,3,4};
-
简化版格式
数据类型[] 数组名 = {元素1,元素2,...}; 举例: int[] arr = {1,2,3,4};
当然下面这种格式也可以:
注意这种写法在java语言中用的不多,但要会,很多人只是在先学了C语言后有写成这种代码的习惯。建议用上面的写法。
3.3.3静态初始化格式详解
-
等号左边:
-
int:数组的数据类型
-
[]:代表这是一个数组
-
arr:代表数组的名称
-
-
等号右边:
-
new:为数组开辟内存空间
-
int:数组的数据类型
-
[]:代表这是一个数组
-
{}:表示数组里面存储的所有元素
-
3.4数组元素访问
3.4.1什么是索引
每一个存储到数组的元素,都会自动的拥有一个编号,从0开始。
这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。 所谓的索引在数组中就指的是下标。
3.4.2访问数组元素格式
数组名[索引];
3.4.3索引的作用:
-
利用索引可以获取数组中的元素
-
利用索引可以把数据存储到数组中
3.4.4示例代码
public class ArrayDemo { public static void main(String[] args) { int[] arr = new int[3]; //输出数组名 System.out.println(arr); //[I@880ec60 //输出数组中的元素 System.out.println(arr[0]); System.out.println(arr[1]); System.out.println(arr[2]); } }
如下是打印一个数组的地址:
解释一下这个输出值的含义
[ 表示数组
I 表示数据类型是int型,如果是double型数组就会打印D
@ 是规定一个符号。
后面的8个数字是16进制的数字,是真真正的地址。
再看C语言的:
只看后八个数字。它们是真正的地址。
练习1:数组的遍历
遍历:把数组里面所有的元素都一一获取出来
代码示例:
//1.定义数组 int[] arr = {1,2,3,4,5}; //2.遍历数组 for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } System.out.println("---------------快速生成最终代码--------------------"); //数组名.fori,这是个快捷方式,务必掌握。
强调一下这个快捷方式:
数组名.fori,这是个快捷方式,务必掌握,点击回车后:
自动生成我们需要的循环代码,而且循环控制是数组的长度。这个无比记住并且在今后写代码尽量用这个快捷方式,能方便很多。
练习2:累加求和
需求:
定义一个数组,存储1,2,3,4,5
遍历数组得到每一个元素,求数组里面所有的数据和
代码示例:
//1.定义数组 int[] arr = {1,2,3,4,5}; //2.定义一个累加变量sum int sum = 0; //3.遍历数组得到数组里面的每一个元素 for (int i = 0; i < arr.length; i++) { //i 依次表示数组中的每一个索引 //arr[i] 依次表示数组中的每一个元素 //System.out.println(arr[i]); sum = sum + arr[i]; } //4.当循环结束之后,表示所有的数据都已经累加成功 System.out.println(sum);
练习3:统计个数
需求:
定义一个数组,存储1,2,3,4,5,6,7,8,9,10 遍历数组得到每一个元素,统计数组里面一共有多少个能被3整除的数字
代码示例:
//1.定义数组1,2,3,4,5,6,7,8,9,10 int[] arr = {1,2,3,4,5,6,7,8,9,10}; //2.定义统计变量 int count = 0; //3.遍历数组得到每一个元素 for (int i = 0; i < arr.length; i++) { //3.判断当前元素是否满足 if(arr[i] % 3 == 0){ count++; } } //4.循环结束之后,就表示数组里面所有的元素都已经统计完毕 System.out.println(count);
练习4:变化数据
需求:
定义一个数组,存储1,2,3,4,5,6,7,8,9,10
遍历数组得到每一个元素。
要求:
1,如果是奇数,则将当前数字扩大两倍
2,如果是偶数,则将当前数字变成二分之一
代码示例:
public class ArrDemo7 { public static void main(String[] args) { /* 定义一个数组,存储1,2,3,4,5,6,7,8,9,10 遍历数组得到每一个元素。 要求: 1,如果是奇数,则将当前数字扩大两倍 2,如果是偶数,则将当前数字变成二分之一 */ // 1 2 3 4 5 6 7 8 9 10 // 2 1 6 2 10 3 14 4 18 5 //1.定义数组 int[] arr = {1,2,3,4,5,6,7,8,9,10}; //2.遍历数组得到每一个元素 for (int i = 0; i < arr.length; i++) { //3.判断每一个元素是奇数还是偶数 if(arr[i] % 2 == 0){ // 偶数,则将当前数字变成二分之一 arr[i] = arr[i] / 2; }else{ // 奇数,则将当前数字扩大两倍 arr[i] = arr[i] * 2; } } //3.当循环结束之后,数组里面所有的数据都已经改变完毕 //再遍历验证一下即可 //一个循环只干一件事情。 //如果想要遍历,再写一个循环即可 for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } } }
这里说一下System.out.print,这个是不换行的写法。而System.out,println是换行的写法,它是先打印,光标再换行。
3.5数组动态初始化
3.5.1什么是动态初始化
数组动态初始化就是只给定数组的长度,由系统给出默认初始化值。
3.5.2动态初始化格式
数据类型[] 数组名 = new 数据类型[数组长度];
int[] arr = new int[3];
3.5.3动态初始化格式详解
-
等号左边:
-
int:数组的数据类型
-
[]:代表这是一个数组
-
arr:代表数组的名称
-
-
等号右边:
-
new:为数组开辟内存空间
-
int:数组的数据类型
-
[]:代表这是一个数组
-
5:代表数组的长度
下图是动态初始化不同数据类型的默认初始值:
-
看一个例子:
可见引用类型的默认初始值为null
3.6数组操作的两个常见小问题
3.6.1索引越界异常
-
出现原因
public class ArrayDemo { public static void main(String[] args) { int[] arr = new int[3]; System.out.println(arr[3]); } }
数组长度为3,索引范围是0~2,但是我们却访问了一个3的索引。
程序运行后,将会抛出ArrayIndexOutOfBoundsException 数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。
-
解决方案
将错误的索引修改为正确的索引范围即可!
3.6.2空指针异常
-
出现原因
public class ArrayDemo { public static void main(String[] args) { int[] arr = new int[3]; //把null赋值给数组 arr = null; System.out.println(arr[0]); } }
arr = null 这行代码,意味着变量arr将不会再保存数组的内存地址,也就不允许再操作数组了,因此运行的时候会抛出 NullPointerException 空指针异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。
-
解决方案
给数组一个真正的堆内存空间引用即可!
3.7数组的练习
3.7.1数组最值
-
最大值获取:从数组的所有元素中找出最大值。
-
实现思路:
-
定义变量,保存数组0索引上的元素
-
遍历数组,获取出数组中的每个元素
-
将遍历到的元素和保存数组0索引上值的变量进行比较
-
如果数组元素的值大于了变量的值,变量记录住新的值
-
数组循环遍历结束,变量保存的就是数组中的最大值
-
-
代码实现:
//扩展1:max的值能不能写0?最好不要写0。 // 一般都会赋值数组中的某个元素 //扩展2:循环从0开始,或者循环从1开始,对结果有没有影响? // 没有 // 如果循环从0开始,那么多了一次,自己跟自己比的过程。 // 对结果没有任何影响,只不过多循环了一次而已。 //1.定义数组存储元素 int[] arr = {33,5,22,44,55}; //2.定义一个变量max int max = arr[0]; //3.遍历数组 for (int i = 1; i < arr.length; i++) { // i 索引 arr[i] 元素 if(arr[i] > max){ max = arr[i]; } } //4.当循环结束之后,max记录的就是最大值 System.out.println(max);
3.7.2遍历数组统计个数
需求:生成10个1~100之间的随机数存入数组
1)求出所有数据的和
2)求所有数据的平均数
3)统计有多少个数据比平均值小
代码示例:
import java.util.Random; public class ArrDemo13 { public static void main(String[] args) { //1.定义数组 int[] arr = new int[10]; //2.生成10个随机数存入数组 Random r = new Random(); for (int i = 0; i < arr.length; i++) { //生成随机数 int number = r.nextInt(100) + 1; //把生成的随机数存入数组 arr[i] = number; } //3.求和 int sum = 0; for (int i = 0; i < arr.length; i++) { //累加 sum = sum + arr[i]; } //4.平均数 int avg = sum / arr.length; //5.统计 int count = 0; for (int i = 0; i < arr.length; i++) { if(arr[i] < avg){ count++; } } //6.循环结束之后打印count System.out.println(count); } }
以下的练习day05学习
3.7.3交换数组中的数据
本题的前置练习1:
交换两个变量的值 int a = 10; int b = 20; //把a原本的值做了临时存储 int c = a; //把b的值交给了a。 a = b; //把c的值交给b b = c; System.out.println(a); System.out.println(b); 本题的前置练习2:
把0索引的元素跟最后一个元素进行交换 int[] arr = {1,2,3,4,5}; //第一个和最后一个交换 // 5 2 3 4 1 int temp = arr[0]; arr[0] = arr[4]; arr[4] = temp; for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); }
需求:
需求:定义一个数组,存入1,2,3,4,5。交换首尾索引对应的元素。
交换前:1,2,3,4,5
交换后:5,4,3,2,1
代码示例:
//1.定义数组 int[] arr = {1, 2, 3, 4, 5}; //2.循环交换数据 for (int i = 0, j = arr.length - 1; i < j; i++, j--) { //交换i和j指向的元素即可 int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } //3.遍历数组 for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); }
这个练习题还是比较重要的,首先我们又另外知道了for循环可以有多个初始化语句,另外就是本题的算法思想,现在我们已经开始在慢慢培养编程思维了。
3.7.4打乱数组中的数据
需求:
定义一个数组,存入1~5。要求打乱数组中所有数据的顺序。
代码示例:
import java.util.Random; public class ArrDemo18 { public static void main(String[] args) { //需求:定义一个数组,存入1~5。要求打乱数组中所有数据的顺序。 //核心: //从0索引开始进行遍历 //拿着遍历到的数据,跟数组中的随机索引处,进行位置交换 //1.定义数组 int[] arr = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; //2.利用循环交换每一个索引上对应的元素 Random r = new Random(); for (int i = 0; i < arr.length; i++) { //生成一个新的随机索引 int randomIndex = r.nextInt(arr.length); //拿着随机索引对应的元素 跟 i 对应的元素进行交换 int temp = arr[i]; arr[i] = arr[randomIndex]; arr[randomIndex] = temp; } //当循环结束之后,就表示数组里面的每一个元素,都跟随机索引进行了交换 //当循环结束之后,此时就好比已经打乱了数组中的数据。 //3.遍历数组 for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } } }
好的,今天的学习结束。