数组
为什么需要学习数组? 存储多个变量的容器
数组的概述: 一组存储相同数据类型的容器
数组的本质也是一个变量,用来存储一组变量的容器
格式: 数据类型[] 数组名 = new 数据类型[数组的长度]; // Java写法
变式: 数据类型 数组名[] = new 数据类型[数组的长度]; // C语言写法
这里的数据类型可以是八大基本数据类型也可以是引用数据类型
数组名满足变量名的命名规范,一般都是复数
new: 在堆区分配内存空间
数组的长度: 表示数组可以存放多少个连续的变量
变量的三要素: 1.声明 2.赋值 3.使用
数组的声明:
表示告诉计算机开辟多大的连续的内存空间
数组的赋值:
地址传递
数组的使用: 访问数组中的元素
如何来访问数组中的元素: 通过下标、索引
数组名[索引]
索引范围 [0,数组的长度)
ArrayIndexOutOfBoundsException
异常名称: 数组索引越界异常
产生原因: 访问了不存在的索引
解决办法: 检查索引是否在 [0,数组的长度) 的范围内
NullPointerException
异常名称: 空指针异常
产生原因: 引用类型的变量没有 new,就访问了对象的成员或者访问了数组的元素
解决办法: 找到错误代码对应的那一行,观察哪些是引用类型,再观察这个引用类型有没有new
数组的初始化
- 1.静态初始化: 初始化的同时给数组的每一个元素赋值,不需要指明数组的长度,系统根据元素的个数动态计算数组的长度
格式:
格式一:数据类型[] 数组名 = {元素1, 元素2, 元素3, … , 元素n};
格式二:数据类型[] 数组名 = new 数据类型[] {元素1, 元素2, 元素3, … , 元素n};
有了格式一为什么有格式二? --> 在传递参数的时候,如果是匿名数组必须使用格式二 - 2.动态初始化: 初始化的同时由系统为每一个元素赋值,必须指明数组的长度,赋值的特点满足堆区的默认值特点
堆区中每个变量都有默认值
byte short int long 默认值 0
float double 默认值 0.0
char 默认值 ‘\u0000’ 就是一个空字符
boolean 默认值 false
引用类型 默认值 null
格式: 数据类型[] 数组名 = new 数据类型[数组的长度]; // Java写法
变式: 数据类型 数组名[] = new 数据类型[数组的长度]; // C语言写法
面试题: 静态初始化和动态的初始化的区别?
值传递和引用传递
方法调用的时候:
形式参数可以是如下类型
八大基本数据类型: 数值本身
引用数据类型: 地址
值传递本质传递的是数值,引用传递传递的是地址
foreach遍历 数组和集合的专属迭代器
for循环的简化
擅长遍历
语句格式:
for(元素类型 元素变量 : 遍历对象){
使用元素变量
}
对比二者的区别:
1.foreach相比普通for,更简洁
2.foreach没有索引,普通for有索引,可以自定义索引
3.foreach的本质还是普通for
int ai[];
int k = (ai = arr).length;
for (int j = 0; j < k; j++)
{
int i = ai[j];
System.out.println(i);
}
可变参数
为什么需要有可变参数? – 针对参数的类型一致,但是个数不一致的情况使用
格式:
参数类型… 变量名
可变参数的特点:
1.可变参数本质是数组
2.可变参数的 … 可以出现在 参数类型 和 变量名的 任意位置
3.可变参数必须出现参数列表的最后
动态初始化的快速初始化方式
1.通过键盘输入
2.通过随机数
public class ArrayDemo07 {
public static void main(String[] args) {
// 1.通过键盘输入
Scanner input = new Scanner(System.in);
int[] arr = new int[5];
/*for (int i = 0; i < arr.length; i++) {
System.out.print("请输入第" + (i+1) + "个数: ");
arr[i] = input.nextInt();
}
System.out.println(Arrays.toString(arr));*/
// 2.通过随机数
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 100);
}
System.out.println(Arrays.toString(arr));
}
}