数组,英文叫Array,是一种数据结构,是用来存放同一数据类型数值的集合。例如存放30个int型数值、存放100个double型数值等等。html
咱们知道使用一个变量,须要先声明一个变量,例如:int a;使用数组一样也须要先声明一个数组变量。假设咱们要声明一个int类型的数组变量,有2种方式:java
int[] a; int b[];
可是通常Java工做者都习惯于第一种方式,由于int[]看起来更像数据类型,后面跟一个变量名。算法
声明变量,其实是在内存中给它分配一块空间。可是数组是存放若干个数据,所以还得继续声明它的大小,即存放多少个数据。Java中使用new运算符来操做。像下面这样:api
a = new int[30];
咱们还能够在声明数组的同时就分配空间:数组
int[] a = new int[30];
上面这条语句声明int型的数组a能够存放30个int的数值。这样,就会在内存中分配30个连续的空间。浏览器
数组大小分配好了之后。咱们要访问数组中的某一个元素的话,能够用一个整型的下标(index)来访问。下标是从0开始的,所以上面的数组a的下标是0~29。好比咱们要访问第29个元素,那么能够用a[28]。这里须要注意,数组一旦被建立了之后,大小就是固定的。若是下标超出范围,例如访问a[30],程序会报异常,异常通常是:“array index out of bounds”,称作“下标越界”。数据结构
给数组的元素赋值就很简单了,就像给一个普通变量赋值同样:工具
a[22] = 22;
咱们还能够在声明数组的时候同时赋值,有两种形式:优化
int[] a = new int[] { 1, 2, 3, 4 }; int[] b = { 1, 2, 3, 4 };
注意第一种形式,[]内不须要指定大小。有的时候,咱们还须要知道数组的大小,能够用a.length来得到。例如咱们想遍历打印数组的值:spa
for (int i = 0; i < a.length; i++) { System.out.println(a[i]); }
综合上面的讨论,咱们能够概括一下数组的3要素:
访问数组的元素用“变量名[下标]”的方式。下标的范围是0~length。若是不在这个范围内,程序会报“下标越界”异常。
用一张图总结一下:
在实际运用中,常常会有遍历数组的需求。上面咱们用for演示过遍历数组的状况。事实上,在Java5.0以后,有另一种for循环的结构,能够很是方便的遍历一个集合中的元素。代码形式为:
for(类型 变量:集合){语句}
咱们看一个例子:
int[] a = new int[] { 1, 2, 3, 4 }; for (int i : a) { System.out.println(i); }
运行结果:
1 2 3 4
这种for循环能够理解为“遍历集合中的每个元素”。
在实际工做中,还会常常碰到须要将一个数组中的所有或部分元素拷贝到另外一个元素中的需求。若是是全量拷贝,有一个很简单的办法:
int[] a = new int[] { 1, 2, 3, 4 }; int[] b = a;
执行以上代码后,数组b和数组a就同样了。可是这样有一个问题,咱们继续编写代码:
int[] a = new int[] { 1, 2, 3, 4 }; int[] b = a; b[3] = 33;// 将数组的b的第4个元素赋值为33 System.out.println(a[3]);// 结果数组a的第4个元素也变成33
咱们修改数组b的第4个元素,结果数组a的第4个元素也跟着一块修改了。这是为何呢?这是由于Java中变量的的赋值,是引用赋值,用内存的表现来解释能够一目了然:
把变量a赋值给变量b,实际上b和a将指向同一个内存地址。所以修改b的元素,实际上就是修改内存中的值,这样a的元素天然也就跟着修改了。咱们称这种拷贝为“浅拷贝”。若是想要实现另外分配一块内存空间给数组b,有没有办法呢?Java给咱们提供了2种方法,一种是用System类的arraycopy方法,还有一种是Java6以后新提供的Arrays类的copyOf方法。具体怎么用?还记得安装JDK的时候,提到过的API文档吗?咱们这时候就须要用到它了。(若是不记得了,回到那一节看一遍)。
笔者的API文档的路径是:D:\Java大失叔\Java\jdk-8u261-docs-all\docs,咱们找到api目录下的index.html,用浏览器打开,能够看到首页:
左上是全部的包,左下是当前包下的类,右边是当前类的API说明。未来咱们会常常用到API文档来查找类的使用说明。咱们先来看一下System的arraycopy方法。
System类在java.lang包下,咱们定位到System类后,找到arraycopy方法,点击方法名,能够进入该方法的详细说明。咱们摘抄方法体:
arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
这个方法的做用就是从源数组src的srcPos下标开始,拷贝length个元素到目标数组dest中,目标数组的起始下标为destPos。咱们直接上代码:
int[] a = new int[] { 1, 2, 3, 4 }; int[] b = new int[4]; System.arraycopy(a, 0, b, 0, 4); b[3] = 33;// 将数组的b的第4个元素赋值为33 System.out.println(b[3]);// 数组b的第4个元素变成33 System.out.println(a[3]);// 数组a的第4个元素仍然是4
接下来,咱们看一下Arrays.copyOf方法,Arrays类在java.util包下,util包提供了不少有用的工具类,Arrays是其中之一,咱们会发现有不少copyOf方法,咱们找到对应int型的:
copyOf(int[] original, int newLength)
这个方法的做用就是将源数组original的全部元素拷贝到一个新的数组中,能够指定新的数组的大小newLength,而后返回新的数组。若是newLength比源数组大小大,那么新数组多余的元素将被赋值为0,若是newLength比源数组大小小,那么将只拷贝newLength个元素。咱们上代码:
int[] a = new int[] { 1, 2, 3, 4 }; int[] b = Arrays.copyOf(a, 5); int[] c = Arrays.copyOf(a, 3); b[0] = 33;// 将数组的b的第4个元素赋值为33 c[0] = 44;// 将数组的b的第4个元素赋值为33 System.out.println(a[0]);// 数组a的第1个元素仍然是4 System.out.println(b[0]);// 数组b的第1个元素变成33 System.out.println(c[0]);// 数组c的第1个元素变成44
数组的排序也能够用Arrays类的sort方法,咱们摘抄方法:
sort(int[] a)
这个方法对数组a进行升序排序。它内部采用的是优化的快速排序算法,这个算法对于大多数的数据集合来讲效率都比较高。咱们看一下代码:
int[] a = new int[] { 1, 4, 2, 3 }; Arrays.sort(a); for (int i : a) { System.out.println(i); }
运行结果:
1 2 3 4
排序以后,按照升序排列了。
Arrays类还有不少有用的方法,这里就不一一列举了,你们之后若是碰到须要对数组进行某些操做的时候,能够想到来查一下Arrays类,看看有没有对应的方法。
Java中还支持多维数组,可是其实在实际运用中不多用到,最多也就用一下二维数组,所以这里只粗略的介绍一下二维数组。咱们常常用到Excel表格,其实就能够当作一个二维数组,例如:
11 |
12 |
13 |
14 |
21 |
22 |
23 |
24 |
31 |
32 |
33 |
34 |
41 |
42 |
43 |
44 |
51 |
52 |
53 |
54 |
声明二维数组、分配空间和赋值访问和一维数组相似,咱们用代码演示:
int[][] table;// 声明一个二维数组 table = new int[5][4];// 分配空间5行4列 table[0][1] = 12;// 第1行第2列赋值为12
对于赋值,也能够和一维数组同样,在声明的同时就赋值:
int[][] table = new int[][] { { 11, 12, 13, 14 }, { 21, 22, 23, 24 } };// 声明一个二维数组,并赋值 int[][] table2 = { { 11, 12, 13, 14 }, { 21, 22, 23, 24 } };// 声明一个二维数组,并赋值
二维数组其实能够当作是一个一维数组,而后该维度数组的每个元素又是一个一维数组。用图能够表示以下:
所以,聪明的你可能发现了,Java的二维数组中,数组的length的值是第一维度的大小。而且咱们在分配二维数组大小的时候,能够只分配第一维度的大小,而后再给第一维度的数组的每个元素分配不一样的大小,例如:
int[][] table = new int[4][];// 只分配第一位维度的大小为4 table[0] = new int[1];// 给table[0]分配大小为1 table[0][0] = 11; table[1] = new int[] { 21, 22 };// 给table[1]分配大小为2,同时赋值 table[2] = new int[] { 31, 32, 33 };// 给table[2]分配大小为3,同时赋值 table[3] = new int[] { 41, 42, 43, 44 };// 给table[3]分配大小为4,同时赋值
这实际上是一个不规则的二维数组。用表格表示以下图:
11 |
|
|
|
21 |
22 |
|
|
31 |
32 |
33 |
|
41 |
42 |
43 |
44 |