简述
数组(Array)是对象中特别的一种类型,它拥有多个基本数据类型值或对象,这些称做数组元素(Element),可通过索引(Index)对其访问。数组类型可以是任何合法的JAVA类型,例如整型、字符型等,同时也可以是数组类型,即可创建多维数组。
声明及创建
数组有以下几种声明方法,其中type表示任何的合法JAVA类型。
type[] arr; // 使用JAVA语法声明一个数组 type arr[]; // 使用C语法声明,不推荐使用 type[] arr = new type[n]; // 声明一个长度为n的数组,其中n为常量或可以计算出常量
// 的表达式,n的最大值为int的最大值 type[] arr = new type[] {ele1,ele2,ele3}; // 声明数组并初始化,eleN为数组元素
type[] arr = {ele1,ele2,ele3}; // 对数组进行初始化,也可省略new type[]
下面给出示例:
1 int[] arr; // 声明一个整型数组 2 /* 3 * int arr[0] = 1; // 错误示例,数组只声明未创建,不能进行操作 4 */ 5 arr = new int[2]; // 创建长度为2的数组 6 arr[0] = 1; // 为其赋值 7 arr[1] = 2; 8 9 System.out.print(arr[0] + " " + arr[1]); // 输出 1 2
若要输出的数组元素较多,用上述的方法,显然效率太低。所以,可以使用foreach语句遍历数组所有元素。
1 for(int ele : arr) // 每次循环会将数组元素的值赋值给ele 2 { 3 System.out.print(ele + " "); // 输出 1 2 4 }
复制
JAVA的对象复制分为浅层复制(Shallow Copy)和深层复制(Deep Copy),数组作为一种对象也是同样的,默认是进行浅层复制。当数组类型是基本类型或String类型时,浅层复制和深层复制没有区别,而数组是引用类型(String除外)就有区别了,在这不做讨论。
先看下面一个例子:
1 int[] src = new int[] {1,2,3,4}; 2 int[] dst = new int[4]; 3 dst = src; // 使用赋值号直接赋值 4 5 for(int ele : dst) 6 System.out.print(ele+" "); // 输出 1 2 3 4 7 8 System.out.println("\n- - - -"); // 分隔线 9 10 src[0] = 5; // 改变源数组中的元素值 11 for(int ele : dst) 12 System.out.print(ele+" "); // 输出 5 2 3 4
上面例子中,只改变了源数组src的中第一个元素的值,但最后输出数组dst时,它的第一个元素的值也改变了。
产生这种情况的原因是,使用赋值号直接赋值,只是一种引用,即最后dst和src只是同一个数组。这种操作使得可以通过dst访问src数组的元素,dst相当于一个访问src的地址,这里的dst有点像C语言的指针。(注记:尝试过创建dst数组时,将它的长度改成小于src的长度(例如3),这时不会报错,而且后来输出还是4个元素。这里不明白原因,不过我想可能是因为dst只是个引用的关系。注记日期:2017.03.11)
若想真正地复制数组,可以遍历数组,然后对其一个个进行赋值,但是使用下面方法可能更好。
使用clone()方法对数组进行复制。
1 int[] src = new int[] {1,2,3}; // 创建一个数组并初始化 2 int[] dst = (int[])src.clone(); // 声明另一个数组dst并复制src的元素,注意需强制转换(注记: 3 // 《JAVA技术手册》上说要强制转换,试过不强制转换也不报错 4 // 注记日期:2017.03.10) 5 6 /* 输出两个数组 */ 7 System.out.print("src = "); 8 for(int ele : src) 9 System.out.print(ele+" "); // 输出 1 2 3 10 11 System.out.print("\ndst = "); 12 for(int ele : dst) 13 System.out.print(ele+" "); // 输出 1 2 3
使用clone()方法只能复制全部元素,灵活性差。若想复制局部元素,就得使用System.arraycopy()方法,下面给出示例(接上个示例)。
1 int[] sub = new int[2]; // 创建长度为2的数组 2 System.arraycopy(src,0,sub,0,2); // 复制src一部分元素到sub中 3 4 System.out.print("\nsub = "); 5 for(int ele : sub) 6 System.out.print(ele+" "); // 输出 1 2
System.arraycopy()方法的参数列表为(Object src,int srcPos,Object dest,int destPos,int length)。
src为源数组,即要被复制数组;
srcPos为源数组的复制起点,即要从此处开始复制数组;
dest为目标数组;
destPost为目标数组的粘贴起点;
length为要从源数组复制的长度。
该方法的源数组和目标数组可以为同一个数组,这样就可以对数组自身进行一些操作。
多维数组
多维数组的声明和创建方法如下,其中type表示任何的合法JAVA类型。
type[][] arr = new type[3][3]; // 声明并创建一个3*3的二维数组 type[][] arr = new type[3][3][3]; // 声明并创建一个3*3*3的三维数组 // 更多维数组以此类推 type[][] arr = new type[3][3]{{1,2,3} , {2,4,6} , {3,6,9} }; // 创建多维数组并初始化, // 可写成一行
创建多维数组时,不必指定该数组的所有维度(Dimension),只需指定最左侧的几个维度,如下例子:
type arr[][][] = new type[3][][]; // 只指定一个维度 type arr[][][] = new type[3][3][]; // 只指定两个维度 type arr[][][] = new type[][3][]; // 错误 type arr[][][] = new type[3][][3]; // 错误
总结
JAVA的数组和C语言的数组一样,都不是动态数组,长度都是固定的。除了文中几个对数组的方法外,JAVA还提供了其他方法,会在以后的博文中介绍。至于文中的注记问题,目前学得暂浅,等之后有时间会进行解决。