数组是相同类型的、用一个标识符名称封装到一起的一个对象序列或基本类型数据序列。定义数组是是通过方括号 [] 来实现的,只需要在类型名后面加一个方括号即可:
int [] a;
这样就给拥有了对数组的一个引用,还没有分配任何空间,而编译器又不允许指定数组的大小,那么为了给数组分配存储空间,就需要使用初始化表达式了,这种初始化操作是由一堆花括号来实现的,如下:
public static void main(String[] args) {
//可以通过花括号进行初始化
int[] a = {1, 2, 3};
//可以将一个数组的值赋给另一个数组
int[] a1 = a;
//数组遍历
for (int i = 0; i < a1.length; i++) {
System.out.println("下标为:" + i + ",数值为:" + a1[i]);
}
}
打印结果:
下标为:0,数值为:1
下标为:1,数值为:2
下标为:2,数值为:3
Java 数组计数是从 0 个元素开始,所以能使用的最大下标数是 length - 1,一旦超过边界数,那么就会出现运行时异常。
如果不确定数组里面有多少个元素,那么可以直接用 new 关键字在数组里创建元素,使用 Random.nextInt() 方法随机指定大小,如下:
public static void main(String[] args) {
//如果是基本类型的数组
int[] b = new int[new Random().nextInt(20)];
//数组长度
System.out.println("基本数组 b 的长度为:" + b.length);
for(int i = 0; i < b.length; i++){
System.out.println(b[i]);
}
//如果是对象数组
Integer[] c = new Integer[new Random().nextInt(20)];
//数组长度
System.out.println("对象数组 c 的长度为:" + c.length);
for(int i = 0; i < c.length; i++){
System.out.println(c[i]);
}
}
打印结果:
基本类型数组 b 的长度为:2
0
0
对象数组 c 的长度为:3
null
null
null
可以基本类型数组的元素都会有一个基本数据类型的初始值(例如 int 类型的初始值为 0),但是非基本类型数组的元素的初始值为 null,这个时候就还需要对数组元素进行赋值操作:
for(int i = 0; i < c.length; i++){
//对非基本类型的数组元素赋值
c[i] = new Random().nextInt(20);
}
如果试图使用数组中的空引用,那么运行时就会产生异常。也可以通过结合花括号来初始化对象数组:
//通过花括号来初始化对象数组
Integer[] d = new Integer[]{1, 2, 3};
我们调用有参方法的时候,通常每个参数只有一个,但是也可以是多个,这种情况有两种写法,如下:
public static void main(String[] args) {
test(new String[]{"1","2"});
test2("1", "2");
test2(new String[]{"1","2"});
}
/**
* 写法一,需要传入数组
* @param str
*/
public static void test(String[] str) {
for (String s : str) {
System.out.println(s);
}
}
/**
* 写法二,可变参数列表,不用编写数组语法
* @param str
*/
public static void test2(String... str) {
for (String s : str) {
System.out.println(s);
}
}
第一种写法必须要传入数组作为参数,但是第二种写法,既可以传入数组也可以直接输入一组参数,再也不用显式地去编写数组了。
同时,可变参数列表还兼容了自动包装机制:
public static void main(String[] args) {
test3(1, 2, 3);
}
/**
* 可变参数列表,类型为 Integer
* @param nums
*/
public static void test3(Integer... nums) {
for (Integer i : nums) {
System.out.println(i);
}
}
可以看到调用的时候,传入的是基本类型,但是编译器将其自动装箱。