数组是什么东西啊?emmm....数组不是东西,它是一种数据结构,可以存放多个数据,但是这些数据是同一种类型哦。
数组就像一个带很多抽屉的柜子,在这个柜子打造完成的时候,就已经确定了它有多少个抽屉,即数组的长度是不可变化的。即便你把所有的抽屉里面的东西都拿走了,抽屉还是那么多个,数组空间依然还在,长度依旧不变。
定义数组
在Java中有两种方式定义数组:
// type表示某种数据类型,可以为常见的int,double等,也可以为自己定义的类
type[] arrayName;
type arrayName[];
上面两种方式中,你能分清哪个是变量名,哪个是变量类型吗?实际上在数组中,变量名是arrayName
,变量类型是type[]
。假设type
是int
,那就表示这是一个存放int类型元素的数组,所以我们更推荐使用第一种方式定义数组。
数组是引用类型,因此定义一个数组时,只是定义了一个引用变量,定义的时候没有指向有效内存,因此定义数组时不能指定数组长度。
数组初始化
静态初始化
也就是程序猿直接给数组变量赋值,这时候由系统决定数组长度。语法格式如下所示:
// a,b,c……表示元素
arrayName = new type[] {a,b,b,...}
type
就是数组元素的数据类型,这地方的type
必须与定义数组变量所使用的type
相同。
当然我们可以把声明和初始化放在一起操作。
type[] arrayName = {a,b,b,...}
示例代码
// 定义数组
int[] arr;
String[] strs;
char[] c;
boolean[] b;
// 静态初始化
arr = new int[] {1,2,3};
// 定义和静态初始化一起
int[] a = {4,5,6};
动态初始化
动态是相对于静态而言,静态初始化的时候,我们直接把所有的元素赋值给变量,一次性操作完成。那么动态初始化的时候,就是在使用的过程中赋值,但是赋值之前我们需要开辟空间出来,不然赋值的会发现没地方放元素。
这时候是程序猿先指定数组的长度,系统为每个数组元素指定初始值。语法格式如下所示:
// length是一个int类型的数字,用来表示数组的长度
arrayName = new type[length];
示例代码
// 动态初始化,5个空间的char类型数组
char[] c;
c = new char[5];
// 声明和初始化合并
int[] arr = new int[10];
动态初始化的时候,因为没有手动赋值,系统会给数组元素设置一个默认值,默认值是什么会根据数组元素类型决定,具体的规则如下所示:
- 整数类型(
byte、short、int、long
),初始值为0; - 浮点数类型(
float、double
)初始值0.0; - 字符类型(
char
) 初始值’\u0000’; - 布尔类型(
boolean
)初始值false; - 引用类型(例如
String
),则数组元素值为null。
示例代码
public class Demo {
public static void main(String[] args) {
// 动态创建一个数组
int[] a = new int[3];
String[] strs = new String[3];
// 输出数组a中的元素默认值
// 输出结果 0 0 0
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
// 输出数组strs中的元素默认值
// 输出结果 null null null
for (int i = 0; i < strs.length; i++) {
System.out.println(strs[i]);
}
}
}
使用数组
数组最常用的操作就是赋值和访问,访问数组最常用的方法就是数组变量名加一个方括号([]
),方括号里面的数字为数组元素的索引值。例如arr[1]
数组中存放的第二个元素。数组索引是从0开始的,第一个数组的索引值为0,最后一个数组元素的索引值为数组长度减1
如果这个数值小于0或者大于等于数组长度,程序编译时不会出现任何错误,运行时会出现异常:java.lang.ArrayIndexOutOfBoundsException: N(数组索引越界异常,N为越界的索引值)
Java里面有一个更简单的方法可以遍历数组:foreach循环,使用foreach循环遍历数组元素时无需获取数组长度,也不需要索引。语法如下所示:
for(type value : array) {
// 自动代码访问每个元素
}
type是数组元素的类型,value是一个形参名。特别注意一点:使用foreach循环时,不能改变数组的值。