一维数组的定义和创建
数组是编程语言中非常常见的一种数据结构,它用来存储一组相同数据类型数据。可以通过整型索引访问数组中的每一个值。在一个数组中,它的类型是唯一的。也就是说,在一个数组里面,只能用于存储一种数据类型的数据而不允许多种数据类型数据。
可以通过数组来保存任何相同数据类型的数据:简单类型或者引用类型。数组本身属于引用类型。
数组被创建以后,它的大小(容量)是不能被改变的,但是,数组中的各个数组元素是可以被改变的。
1.定义数组
定义一个一维数组很简单,可以使用下面两种方式:
type[] var_name,如:int[] a;
或
type var_name,如int a[];
通过上面两种方式中的一种,仅仅声明了一个数组变量,并没有创建一个真正的数组。这个时候还不能访问这个数组。
上面两种声明数组的方式,可以任选一种,它们之间并没有优劣之分。一般来说,选择第一种方式比第二种方式要直观一些,可以将左边的type[]看作是变量类型,而将arr_name单纯的作为变量名。
下面这段代码声明了不同数据类型的数组:
//int数组
int[] intArray;
//字符型数组
char[] charArray;
//布尔型数组
boolean[] booleanArray;
//对象数组(引用类型数组)
Student[] studentArray;
2.创建数组
在声明数组时并没有指定数组的大小,也没有给数组分配存储数据的内存空间。可以通过new 操作符来创建一个数组:
int[] a;
a = new int[100];
这条语句创建了一个可以存储100个整型数据的数组,也就是分配了100个可以被int类型数据占用的内存空间。
数组的索引从0开始到99。
可以通过数组名和数组索引来唯一地确定数组中的任何一个元素,例如,要访问数组a的第一个元素,可以通过a[0]来访问,要访问第100个元素,可以通过a[99]来访问,要想访问第n个元素,可以通过a[n-1]来访问。
可以用“数组名.length”来获得一个数组的长度。如上面的数组,可以用a.length来获得它的长度为100。
可以将数组的声明和数组大小的分配放到一块来完成,如下:
type[] arr_name = new type[num];
例如,上面的数组a的声明和数组大小定义可以合并为如下的语句来完成:
int[] a = new int[100];
如果需要声明一个存放引用类型数据的数组,使用的方法也是一样的:
String[] s = new String[40];
public class ArrayDf {
public static void main(String[] args) {
int[] intArray;
intArray = new int[10];
System.out.println("数组长度:" + intArray.length);
}
}
在上面这个程序中,首先声明了一个int类型的数组intArray,然后,通过new 操作符来给这个数组设置了它的长度以及给这个数组分配了存放10个int类型数据的内存空间。
通过intArray.length可以得到这个数组的长度,在这里为10。
编译并运行这个程序,将在控制台上得到如下的输出结果:
数组长度:10
一维数组的初始化
在创建成功一个数组后,它将完成如下三个动作:
创建一个数组对象;
在内存中给数组分配存储空间;
给数组的元素初始化一个相应的数据类型的默认值。比如,将int类型的数组各个元素初始化成0,引用类型是null等。
public class ArrayDf {
public static void main(String[] args) {
int[] intArray;
intArray = new int[10];
System.out.println("第一个元素默认初始化值是:" + intArray[0]);
}
}
在这个程序中,首先声明了一个int类型的数组,然后,利用new操作符创建了一个长度为10的数组,它将给这个数组分配存储空间并且初始化这些数组元素,在这里,讲给这些数组元素一个值0;最后,试图向控制台打印出这个数组第一个元素的值。
因为Java中的数组索引(下标)是从0开始的,所以,第一个数组元素对应的索引为0。所以可以通过intArray[0]的方式来得到数组的第一个元素的值。
编译并运行这个程序,将打印出如下的信息:
第一个元素默认初始化值是:0
其实,此时在这个数组中的任何一个元素的值都是0。读者可以自己修改数组的索引来获得不同的数组元素,注意这个数组的索引取值在0~9之间。
但是,通常情况下,我们定义一个数组并不是想用系统自动给的默认值,而是我们自己给数组的值。这个时候,就需要对数组进行初始化操作。也就是说,给数组的各个元素指定象赢得值。
数组的初始化操作分为两种方式:
静态初始化;
动态初始化。
下面我们来看这两种初始化方式的方法以及它们的区别。
静态初始化
所谓静态初始化,就是在定义数组的时候就对数组进行初始化,如下:
int k[] = {1,3,5,7,9};
在这个例子中,定义了一个int类型的数组k,并且用大括号中的数据对这个数组进行了初始化,各个数据之间用“,”分割开。
此时数组的大小由大括号中的用于初始化数组的元素个数决定,注意不要在数组声明中指定数组的大小,否则将会引起错误。
在这个例子中,我们将数组声明、数组的创建以及数组的初始化都放在了同一条语句中,在这边并没有使用到new来创建这个数组。
来看一个静态初始化的例子:
public class StaticInitArray {
public static void main(String[] args) {
int a[] = { 1, 3, 5, 7, 9, 11 };
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
}
在这个例子中,利用静态方式对数组进行初始化。这个数组的长度是数组中的元素的个数:6。然后用一个for循环将数组的各个元素取出来打印到控制台。程序执行的结果如下:
1
3
5
7
9
11
注意在这边用到了前面所论述的用于获得数组长度的方法:使用数组的length属性,用它来获得数组的长度。
在Java中,还可以利用静态初始化的方法来初始化一个匿名的数组,方法如下:
new type[] {… …}
例如:new String[] {“abc”,”cde”,”efg”}
可以通过这种方法来重新初始化一个数组,例如,有一个String类型的数组,它通过下面的静态方式被初始化:
String[] s = {“tom”,”jerry”,”mickey”};
此时,可以对s这个数组变量进行重新初始化,如下:
s = new String[]{“abc”,”cde”,”efg”};
这条语句等同于下面的两条语句:
String[] temp = {“abc”,”cde”,”efg”};
s = temp;
动态初始化
所谓的动态初始化,就是将数组的定义和数组的初始化分开来进行。
例如,对数组中的元素一个个的分别指定它们各自对应的值:
int a = new int[3];
a[0] = 1;
a[1] = 10;
a[2] = 100;
或者用一个循环来对一个数组一次赋值,如:
int[] a;
a = new int[10];
for (int i = 0;i<10;i++){
a[i] = 2*i+1;
}
再来看一个char类型数组的动态初始化的例子:
char[] s;
s = new char[26];
for ( int i=0; i<26; i++ ) {
s[i] = (char) ('A' + i);
}
数组元素的引用
可以通过数组名和数组索引来引用一个数组元素。
数组索引可以是一个整数或者一个整数表达式。
注意,数组的索引从0开始到数组长度减1,比如,数组长度为n,则索引的范围为0~(n-1)。
例如,由一个名为arr的长度为10的数组,如果需要取得其中第5个元素的值,只需要通过arr[4]的方式就可以取得了。
在使用数组名加数组索引的方式来取得数组的元素时,注意元素的索引必须小于数组的长度,也就是只能在0~(n-1)之间,否则会引起数组越界的异常: java.lang.ArrayIndexOutOfBoundsException。
可以使用数组的一个属性length来获得数组的长度。
数组的拷贝
可以将一个数组变量拷贝给另一个数组变量,这个时候,这两个数组变量均指向同一个数组。通过任何一个数组变量进行操作,均会对另一个数组变量中的数组产生影响。
请看下面这个例子:
public class ArrayCopy1 {
public static void main(String[] args) {
int[] a = { 12, 3, 19, 2, 10, 13, 9 };
int[] b;
b = a;
System.out.println("Before Modifying:");
for (int i = 0; i < a.length; i++) {
System.out.print("a[" + i + "]=" + a[i] + " ");
}
System.out.println("");
b[3] = 31;
System.out.println("After Modifying:");
for (int i = 0; i < a.length; i++) {
System.out.print("a[" + i + "]=" + a[i] + " ");
}
}
}
这个程序首先初始化了一个int类型的数组a,然后,将这个数组变量拷贝给另一个int类型的数组b,这个时候,数组变量a和b均指向同一个数组,如果通过数组变量b来对数组的内容进行修改,也会反映到数组变量a中。
执行这个程序后的结果是:
Before Modifying:
a[0]=12 a[1]=3 a[2]=19 a[3]=2 a[4]=10 a[5]=13 a[6]=9
After Modifying:
a[0]=12 a[1]=3 a[2]=19 a[3]=31 a[4]=10 a[5]=13 a[6]=9
这是因为数组本身是引用类型,就像前面提到的,变量赋值是完成了值传递,这个值是数组对象的引用,根据引用,修改的数组对象是同一个。
如果只是需要将数组的值拷贝到另一个数组,可以使用System的一个静态方法arraycopy,它有5个参数:from、fromIndex、to、toIndex、count,它的意思是将数组from中的索引为fromIndex开始的元素,拷贝到数组to中索引为toIndex的位置,拷贝的元素个数为count个。
看一个使用System类的arraycopy()方法来拷贝数组值的例子:
public class ArrayCopy2 {
public static void main(String[] args) {
int[] a = new int[10];
int[] b = new int[10];
System.out.println("Before Copying:");
for (int i = 0; i < 10; i++) {
a[i] = i + 1;
b[i] = (i + 1) * 100;
System.out.print("b[" + i + "]=" + b[i] + " ");
}
System.out.println("");
System.arraycopy(a, 2, b, 5, 5);
System.out.println("After Copying:");
for (int i = 0; i < b.length; i++) {
System.out.print("b[" + i + "]=" + b[i] + " ");
}
}
}
执行这个程序后在控制台上打印的结果如下:
Before Copying:
b[0]=100 b[1]=200 b[2]=300 b[3]=400 b[4]=500 b[5]=600 b[6]=700 b[7]=800 b[8]=900 b[9]=1000
After Copying:
b[0]=100 b[1]=200 b[2]=300 b[3]=400 b[4]=500 b[5]=3 b[6]=4 b[7]=5 b[8]=6 b[9]=7
通过这种方式拷贝数组,只是将a数组中指定元素的值拷贝给了b数组中的指定元素,a数组本身并不发生变化。
多维数组
1.多维数组的定义
Java中支持多维数组,也就是“数组的数组”。
多维数组的声明是通过每一维一组方括号的方式来实现的。
二维数组:int[][],double[][]等。
三维数组:float[][][],String[][][]等。
2.多维数组的创建
当使用new 来创建多维数组时,不必指定每一维的大小,而只需要指定最左边的维的大小就可以了。如果你指定了其中的某一维的大小,那么所有处于这一维左边的各维的大小都需要指定。
下面是一些创建多维数组的例子:
boolean[][] b = new boolean[10][3];
int[][] a = new int[5][];
String[][][] = new String[4][5][6]
double[][][] = new double[40][][]
3.多维数组初始化
在知道数组元素的情况下,可以直接初始化数组,不必调用new来创建数组,这和一维数组的静态初始化类似:
int[][] a = {{1,2},{10,2},{20,1}}
在引用多维数组的时候,通过指定数组名和各维的索引来引用。
除了静态初始化外,多维数组也可以通过数组声明和初始化分开的动态初始化方法来对数组进行初始化,如:
int a[][] = new int[4][5];
int b[][] = new int[3][]
b[0] = new int[4];
b[1] = new int[3];
b[2] = new int[5];