数组是一组数据的集合,数组中的每个数据称为元素。数组也是Java对象。数组中的元素可以是任意类型(包括基本类型和引用类型),但同一个数组里只能存放类型相同的元素。
创建数组的步骤:
- 声明一个数组类型的引用变量,简称为数组变量
- 用 new 关键字构造数组的实例。 new 关键字为数组分配内存,并且为数组中的每个元素赋予默认值。
- 初始化,即为数组的每个元素设置合适的初始值。
数组变量的声明
下面的代码声明了两个引用变量scores和names,它们分别为int数组类型和String数组类型:
[]在后面也是合法的:
int scores[];
String names[];
两维或者两维以上的数组变量的声明,下面三种形式都可以:
int [][] x;
int x[][];
int []x[];
声明数组变量的时候,不能指定数组的长度,是非法的:
int x[1]; //编译出错
int y[1][2]; //编译出错
创建数组对象
数组对象创建时候,也是用 new 关键字:
int [] scores=new int [100]; //创建一个int数组,存放100个int数据
new 关键字执行的步骤:
- 在堆区中为数组分配内存空间,上面的数组包含100个元素,每个元素是int类型,占用4个字节,整个数组在内存中占用400个字节。
- 为数组中的元素赋予其数据类型的默认值。以上int数组中的每个元素都是int类型,因此它们默认值都是0。
- 返回数组对象的引用。
Java类的程序入口方法main(String args[]),有个有意思的现象,如果运行时候没有输入参数,那么main()方法的参数args并不是null,而是一个长度为0的数组,例如:
public class MainTest{
public static void main(String[] args) {
System.out.println(args. length );
}
}
运行后,将打印数组args的长度为0
数组创建后需要注意一点,它的长度是固定的。数组对象的长度是无法改变的,不过数组变量可以改变所引用的数组对象。例如:
int [] x=new int [3];
x=new int [4];
这段代码创建了两个数组对象,每个数组对象的长度是无法改变的。
访问数组的元素和长度
数组中的每个元素都有一个下标(索引)。数组中的第一个元素的下标为0,第二个为1,依次类推。
String names[]=new String [2];
names[0]=”Hello”;
System.out.println(names[0]);
System.out.println(names[1]);
上面代码中names数组的最后一个元素为names[1],如果访问names[2],由于索引超出了names数组的边界,运行时会抛出ArrayIndexOutOfBoudsException(运行时异常)。
这种异常时由于程序员编写的代码错误引起的,应该在调试阶段就消除掉。
数组变量没有引用数组对象,不能访问其元素:
public class Demo {
static int [] x;
public static void main(String[] args) {
System.out.println(x);//打印null
System.out.println(x[0]); //抛出NullPointerException
}
}
当数组的元素是引用类型,数组中存放的是对象的引用,而不是对象本身。下面的代码是先创建了一个 StringBuffer 对象,然后将其引用加入到了一个StringBuffer数组中:
StringBuffer sb=new StringBuffer();
StringBuffer [] sbs=new StringBuffer[1];
sbs[0]=sb;
数组都有一个length属性,表示数组的长度,它的声明形式为:
public final length;
可以看到被public final修饰,因此只可以读取length属性,不可以更改它的值。
数组的初始化
数组创建后,每个元素被自动赋予其数据类型的默认值。另外,还可以在程序中将数组元素显式的初始化。
int [] x=new int[5];
for(int i=0;i<x.length;i++)
x[i]=x.length-1;
上面代码也可以这样:
int [] x=new int[]{-1,0,1,2,3};
int [] y={-1,0,1,2,3};
不过不可以这样:
int x[] =new int [5]{5,4,3,2,1};
多维数组以及不规则数组
Java支持多维数组,并且支持不规则数组,即多维数组中两维以上的子数组的长度不一样。
可能不好理解,举个例子:假定某个旅馆中有3层楼,第1层有4个房间,第2层有3个房间,第3层有5个房间。某一天客人的住宿情况如下图
可以用两维不规则数组来存储各个房间的客人信息:
String[][] rooms=new String[3][];
rooms[0]=new String[]{“Tom”,”Mike”,”Jack”,null};//第一层
rooms[1]=new String[]{“Mary”,null,”Linda”};//第二层
rooms[2]=new String[]{null,”Jane”,null,null,”Rose”};//第三层
也可以写成:
String[][] rooms={
{“Tom”,”Mike”,”Jack”,null},
{“Mary”,null,”Linda”},
{null,”Jane”,null,null,”Rose”}
};
下面程序打印各个房间的信息:
for(int i=0;i<rooms.length;i++){
for(int j=0;j<rooms[i].length;j++){
int roomNumber=(i+1)*100+j+1;
System.out.println(roomNumber+”房间:”+rooms[i][j]);
}
}
打印结果:
101房间:Tom
102房间:Mike
103房间:Jack
104房间:null
201房间:Mary
202房间:null
203房间:Linda
301房间:null
302房间:Jane
303房间:null
304房间:null
305房间:Rose
上面宾馆的楼成熟固定楼层房间数不固定,第一维数组先创建,第二维长度各不相同。如果有3层楼,并且每一都有4个房间,那么可以按如下方式创建rooms数组:
String [][] rooms=new String[3][4];
三维不规则数组,比二维多一维,下面代码中第一维数组长度是2,第二维数组的长度是3,第三维数组的长度各不相同:
String [][][] ss=new String[2][3][];
注意多维数组创建时,必须按照从低纬度到高纬度的顺序创建每一维数组,下面代码是非法的:
int [][][] b=new int [2][][3];
调用数组对象的方法
数组继承了Object类,因此继承了Object的所有方法。下面代码调用了对象的equals方法:
int a[]=new int [4];
int b[]=new int [4];
System.out.println(a.equals(b)); //打印false
数组实用类:Arrays
在java.util包中,有一个用于操作数组的实用类:java.util.Arrays。提供了一系列静态方法:
- equals(): 比较两个数组是否相同。只有当两个数组中元素数目相同,并且对应位置的元素都相同时,才表明数组相同。
- fill(): 向数组中填充数据。
- sort(): 把数组中的元素按升序排列。如果数组中的元素为引用类型,会采用自然排序方式。
- parallelSort(): 开启多个线程,以并发的方式对数组中的元素进行排序,提高排序的效率,JDK8开始新增的。
- binarySearch(): 按照二分查找算法,查找数组中值与给定数据相同的元素。在调用该方法时,必须保证数组中的元素已经按照升序排列,这样才能得到正确的结果。
- asList(): 把数组转换为一个List对象,将其返回。
- toString(): 返回包含数组中所有元素信息的字符串。
- fill(boolean[] a,boolean var ): 把boolean数组中的所有元素值设为var。
- fill(char[] a,char var): 把char数组中的所有元素值设为var。
- fill(int[] a,int var): 把int数组中的所有元素值设为var。
- fill(float[] a,float var): 把float数组中的所有元素值设为var。
- fill(Object[] a,Object var): 把Object数组中的所有元素值设为var。
用符号“…”声明数目可变参数
有这样一个场景,需要实现一个max方法,功能是从一组int类型的数据中找出最大值。这组数据的数目不固定,数目范围是2~6。大家很快想到的是定义多个max()方法的重载方法:
int max(int a,int b)
int max(int a,int b,int c)
…
int max(int a ,int b,int c,int d,int e,int f)
也可能想到更灵活的方式,使用一个int类型的数组来作为max()方法的参数:
int max(int [] a)
其实还有更简洁的方式,在JDK5之后增加了一个新特性——用符号“…”来声明数目可变参数(简称为可变参数)。可变参数用于参数的数目不固定,而类型固定的情况。
int max(int … a)
可变参数具有以下特点:
- 只能出现在参数列表的最后,作为最后一个参数。相比于数组类型,就显得有局限性了。
void method (int p1,int p2,String … p3);//合法
void method (int p1,String … p3,int p2);//不合法
- 符号“…”位于参数类型和参数名之间,前后有空格都可以
- Java虚拟机在运行时为可变参数隐含创建一个数组,因此在方法体内允许以数组的形式访问可变参数。
max(1,2,3,4) //合法
max(new int[]{1,2,3,4})//合法
目录: