一.一维数组的创建及使用
**一维数组的创建有两种形式:
1)先声明,再用new运算符进行内存分配
- 1
- 2
- 1
- 2
数组元素的类型决定了数组的数据类型,它可以是Java中的任意数据类型,包括简单类型和组合类型。数组名字为一个合法的标识符,符号“[ ]”指明该变量是一个数组类型变量。单个“[ ]”表示要创建的数组是一个一维数组。
例如:
声明一个一维数组,实例代码如下:
- 1
- 2
- 1
- 2
声明数组以后,不能马上访问它的任何元素,因为声明数组只是给出了数组名字和元素的数组类型,要想真正使用数组,还要为它分配内存空间。在为数组分配内存空间时必须指明数组的长度。
为数组分配内存空间的语法格式如下:
- 1
- 1
数组名称:被连接到数组变量的名称;
数组元素的个数:指定数组中变量的个数,即数组的长度;
例如:
为数组分配内存,实例代码如下:
- 1
- 1
以上代码表示要创建一个有5个元素的整型数组,并且将创建的数组对象赋给引用变量arr,即引用变量arr引用这个数组,如下图所示:
数组的下标是从0开始,由于创建的数组arr有5个元素,因此数组中元素的下标为0-4。
说明:
使用new关键字为数组分配内存时:
整型 数组中各个元素的初始值都为0;
浮点型 (float double)的初始值为0.0;
字符型 的初始值为\u0000;
布尔型 的初始值为false;
2)声明的同时为数组分配内存
这种创建数组的方法是将数组的声明和内存的分配合在一起执行。
语法如下:
- 1
- 1
例如:
声明并为数组分配内存,实例代码如下:
- 1
- 1
上面的代码创建了数组month,并指定了长度为12.这种创建数组的方法也是java程序编写过中普遍的用法。
二.初始化一维数组
数组与基本数据类型一样可以进行初始化操作。数组的初始化可分别初始化数组中的每个元素,数组的初始化有以下两种形式:
- 1
- 2
- 1
- 2
从中可以看出,数组的初始化就是包括在大括号内用逗号分开的表达式列表。用逗号(,)分割数组中的各个元素,系统自动为数组分配一定的空间。用第一种初始化方式,将创建5个数组,分别为1、2、3、4、5.第二种初始化方式,会创建4个元素的数组,分别为23、34、45、56。
1)使用一维数组
在java集合中的一维数组是常见的一种数据结构,下面的实例是使用一级数组将1-12月各月的天数输出。
例如:
在项目中创建类,在主方法中创建int型数组,并实现将各月的天数输出。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
输出结果:
三.二维数组的创建与使用
如果一维数组中的各个元素仍然是一个数组,那么它就是一个二维数组。
二维数组常用于表示表,表中的信息以行和列的形式组织,第一个下标代表元素所在的行,第二个下标代表元素所在的列。
小知识:
数组的 length属性:
表示数组的长度,具有以下特点:
1)length的返回值是int型;
2)数组的长度不可以定义成负数;
3)length的值是常量。
1)二维数组的创建
二维数组可以看作是特殊的一维数组,因此,二维数组的创建同样也有两种方式。
(1)先声明,再用new运算符进行内存分配
语法如下:
- 1
- 2
- 1
- 2
例如:
声明二维数组,实例代码如下:
- 1
- 1
同一维数组一样,二维数组在声明时也没有分配内存空间,同样要使用new 关键字来分配内存然后才可以访问每个元素。
对于高维数组,有两种为数组分配内存的方式:
a)直接为每一维分配内存空间
例如:为每一维数组分配内存,实例代码如下:
- 1
- 1
上述代码创建了二维数组a,二维数组a中包括两个长度为4的一维数组,内存图分配如下:
b)分别为每一维分配内存
- 1
- 2
- 3
- 1
- 2
- 3
(2)声明的同时为数组分配内存
第二种方式同第一种实现的功能相同。首先指定最左边维数的内存,然后单独地给余下的维数分配内存。通过第二种方式为二维数组分配内存,如下图所示:
2)二维数组的初始化
二维数组的初始化与一维数组初始化类似,同样可以使用大括号完成。
语法如下:
- 1
- 1
type:数组数据类型;
arrayname:数组名称,一个合法的标识符;
value:数组中各元素的值;
例如:
- 1
- 1
初始化二维数组后,要明确数组的下标都是从0开始。例如,上面的代码中,myarr[1][1]的值为10。
int型二维数组是以int a [][]来定义的,所以可以直接给a[x][y]赋值。例如,给a[1]的第二个元素赋值的语句如下:
- 1
- 1
3)使用二维数组
二维数组在实际应用中用得非常广泛。下面的实例就是使用二维数组输出 一个3行4列且所有元素都是0的矩阵。
例如:
在项目中创建类,在主方法中编写代码实现输出一个3行4列的元素都为0的矩阵。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
输出结果:
0000
0000
0000
说明:
对于整型二维数组,创建成功后,系统会赋值给数组中每个元素的初始值为0.
四.数组的基本操作
Java.util包的Arrays类包含了用来操作数组(如排序和搜索)的各种方法。
1.遍历数组
遍历数组就是获取数组中的每个元素。通常遍历数组都是使用for循环来实现。遍历一维数组很简单,也很好理解,下面详细介绍遍历二维数组的方法。
遍历二维数组需要使用双层for循环,通过数组的length属性可获得数组的长度。
例如:
在项目中创建类,在主方法中编写代码,定义二维数组,实现将二维数组中的元素呈梯形输出。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
输出结果:
1
23
456
在遍历数组时,使用foreach语句可能会更简单。下面的实例就是通过foreach语句遍历二维数组。
例如:在项目中创建类,在主方法中定义二维数组,使用foreach语句遍历二维数组:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
输出结果:
数组中的元素是:
4、3、1、2
2.填充替换数组元素
数组中的元素定义完成后,可通过Arrays类的静态方法fill()来对数组中的元素进行替换。该方法通过对各种重载形式可完成对任意类型的数组元素的替换。fill()方法有两种参数类型,下面以int类型数组为例介绍fill()方法的使用方法。
(1)fill(int[] a,int value)
该方法可将指定的int值分配给int型数组的每个元素。
语法如下:
- 1
- 1
a:要进行元素替换的数组;
value:要存储数组中所有元素的值;
例如:
在项目中创建类,在主方法中创建一维数组,并实现通过fill()方法填充数组元素,最后将数组中的各个元素输出。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
输出结果:
第0个元素是8
第1个元素是8
第2个元素是8
第3个元素是8
第4个元素是8
(2)fill(int[] a ,int fromIndex,int toIndex,int value)
该方法将指定的int值分配给int型数组指定范围中的每个元素。填充的范围从索引 fromIndex (包括)一直到索引 toIndex(不包括)。如果fromIndex == toIndex, 则填充范围为空。
语法如下:
- 1
- 1
a:要进行填充的数组;
fromIndex:要使用指定值填充的第一个元素的索引(包括);
toIndex:要使用指定值填充的最后一个元素的索引(不包括);
value:要存储在数组所有元素中的值。
注意:
如果指定的索引的位置大于或等于要进行填充的数组的长度,则会报ArrayIndexOutOfBoundsException(数组越界异常)。
例如:
在项目中创建类,创建一维数组,并通过fill()方法替换数组元素,最后将数组中的各个元素输出。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
输出结果:
3.对数组进行排序
通过Arrays类的静态sort()方法可以实现对数组的排序。sort()方法提供了多种重载形式,可对任意类型的数组进行升序排序。
语法如下:
- 1
- 1
其中,object是指进行排序的数组名称。
例如:
在项目中创建类,在主方法中创建一维数组,将数组排序后输出。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
输出结果:
8
12
23
42
上述实例是对数组进行排序,java中的String类型数组的排序算法是根据字典编排顺序排序的,因此数字排在字母前面,大写字母排排在小写字母前面。
4.复制数组
Arrays类的copyOf()方法与copyOfRange()方法可以对数组的复制;
copyof()方法是复制数组至指定长度;
copyOfRange()方法则将指定数组的长度复制到一个新数组中。
(1)copyOf()方法
该方法提供了多种重载形式,用于满足不同类型数组的复制。
语法如下:
- 1
- 1
arr:要进行复制的数组;
newlength:int型常量,指复制后的数组长度。如果新数组的长度大于数组arr的长度,则用0填充(根据复制数组的 类型 来决定填充的值,整型数组用0填充, char型数组则用null填充);如果复制后的数组长度小于数组arr的长度,则会从数组arr的第一个元素开始截取至满足新数组长度为止。
例如:
在项目中创建类,在主方法中创建一维数组,实现将此数组复制得到一个长度为5的新数组,并将新数组输出。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
输出结果:
23
42
12
0
0
(2)copyOfRange()方法
该方法同样提供了多种重载形式。
语法如下:
- 1
- 1
arr:要进行复制的数组对象;
fromIndex:指定开始复制数组的索引位置。fromIndex必须在0至整个数组的长度之间。新数组包括索引是fromIndex的元素。
toIndex:要复制范围的最后索引位置。可大于数组arr的长度。新数组不包括索引为toIndex的元素。
例如:
在项目中创建类,在主方法中创建一个数组,并将数组中的索引位置是0-3之间的元素复制到新数组中,最后将新数组输出。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
输出结果:
23
42
12
5.数组查询
Arrays类的binarySearch()方法,可使用二分搜索法来搜索指定数组,以获得指定对象。该方法返回要搜索元素的索引值。binarySearch()方法提供了多种重载形式,用于满足各种类型数组的查找需要。binarySearch()方法有两种参数类型.
(1)binarySearch(Object[],Object key)
语法如下:
- 1
- 1
a:要搜索的数组;
key:要搜索的值。
如果key包含在数组中, 则返回搜索值的索引;否则返回-1或“-”(插入点)。插入点是搜索键将要插入数组的那一点,即第一个大于此键的元素索引 。
例如:
查询数组元素,代码如下:
- 1
- 2
- 3
- 1
- 2
- 3
index的值为 -2
上面的代码中变量index 的值是元素“8”在数组arr中索引在0-1内的索引位置。由于在指定的范围内并不存在元素“8”,index的值是“-”(插入点)。如果对数组进行排序,元素“8”应该在“25”的前面,因此插入点应是元素“25”的索引值,所以index的值为-2.
如果数组中的所有元素都小于指定的键,则为a.length(注意,这保证了当且仅当此键被找到时,返回的值将大于等于0)。
注意:
必须在进行此调用之前对数组进行排序(通过sort()方法)。如果没有对数组进行排序,则结果是不确定的。如果数组中包含多个带有指定值的元素,则无法保证找到的是哪一个。
例如:
在项目中创建类,在主方法中创建一维数组ia,实现查找元素4在数组ia中的索引位置。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
输出结果:
4的索引位置是:1
说明:
返回值“1”是对数组ia进行排序后元素4的索引位置。
(2)binarySearch(Object[], int fromIndex,int toIndex,Object key)
该方法在指定的范围内检索某一元素。
语法如下:
- 1
- 1
a:表示要进行检索的数组;
fromIndex:指定范围的开始处索引(包含);
toIndex:指定范围的结束处索引(不包含);
key:要搜索的索引。
在使用该方法之前同样要对数组进行排序,来获得准确的索引值。如果要搜索的元素key在指定的范围内,则返回搜索键的索引;否则返回-1或“-”(插入点)。如果范围中的所有元素都小于指定的键,则为toIndex(注意,这保证了当且仅当此键被找到时,返回的值将大于等于0)。
注意:
如果指定的范围大于或等于数组的长度,则会报出ArrayIndexOutBoundsException异常。
例如:
在项目中创建类,在主方法中创建String数组,实现查找元素”cd”在指定范围的数组str中的索引位置。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
输出结果:
cd的索引位置是:1
五.数组排序算法
数组有很多处常用的算法,本节将介绍常用的排序算法,包括冒泡排序法、直接选择排序法和反转排序。
1.冒泡排序
在程序设计中,经常需要将一组数列进行排序,这样更加方便统计与查询。程序常用的排序方法有:冒泡排序、选择排序和快速排序等。这次我们介绍冒泡排序法,它以简洁的思想与实现方式而备受青睐。
冒泡排序是最常用的数组排序算法之一,它排序数组元素的过程总是将小数往前放、大数往后放,类似于水中气泡往上升的动作,所以称做冒泡排序 。
1)基本思想
冒泡排序的基本思想是对比相邻的元素值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(也就是交换 两个元素的位置),这样较小的元素就像是气泡一样从底部上升到顶部。
2)算法示例
冒泡算法由双层循环实现,其中外层循环用于控制排序轮数,一般为要排序的数组长度减1次,因为最后一次循环只剩下一个数组元素,不需要对比,同时数组已经完成排序了。而内层循环主要用于对比数组中每个邻近元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少,例如,一个拥有6个元素的数组,在排序过程中每一次循环的排序过程和结果如下图所示:
第一轮外层循环时把最大的元素63移动到了最后面(相应地,比63小的元素向前移动,类似气泡上升),第二轮外层循环不再对比最后一个元素值63,因为它已经被确认为最大(不需要上升),应该放在最后,需要对比和移动的是其他剩余元素,这次将元素24移动到63的前一个位置,其他循环将以此类推,继续完成排序任务。
3)算法实现
下面来介绍一下冒泡排序的具体用法。
例如:
在项目中创建类,这个类的代码将实现冒泡排序的一个演示,其中排序使用是正序。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
说明一下:
可能是自己太笨了,这段代码我死活也执行不出来,那个BubbleSort自己也没有看懂,后来就把代码简单改了改,改成了下面那样:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
输出结果:
1>3>4>15>24>63
从实例的运行结果来看,数组中元素已经按从小到大的顺序排列好了。冒泡排序的主要思想就是:把相邻两个元素进行比较,如满足一定条件则进行交换(如判断大小或日期前后等),每次循环都将最大(或最小)的元素排在最后,下一次循环是对数组中其他的元素进行类似操作。
2.直接选择排序
直接选择排序方法属于选择排序的一种,它的排序速度要比冒泡排序快一些,也是常用的排序算法 。
1)基本思想
直接选择排序的基本思想是将指定排序位置与其他数组元素分别对比,如果满足条件就交换元素值,注意这里区别冒泡排序,不是交换相邻数组,而是把满足条件的元素与指定的排序位置交换(如从最后一个元素开始排序),这样排序好的位置逐渐扩大,最后整个数组都成为已排好序的格式。
好比有一个小学生,从包含数字1-10的乱序的数字堆中分别选择合适的数字,组成一个1-10的排序,这个学生首先从数字堆中选出1,放在第一位,然后选出2(注意这时数字堆中已经没有1了),放在第二位,依此类推,直到其找到数字9,放到8的后面,最后剩下10,就不用选择了,直接放到最后就可以了。
与冒泡排序相比,直接选择排序的交换次数要少很多,所以速度会快些。
2)算法示例
每一趟从待排序的数组元素中选出最小(或最大)的一个元素,顺序的放在已排好序的数列最后,直到全部待排序的数据元素排完。
例如:
初始数据资源 【63 4 24 1 3 15】
第一趟排序后 【15 4 24 1 3 】63
第二趟排序后 【15 4 3 1 】24 63
第三趟排序后 【1 4 3 】15 24 63
第四趟排序后 【1 3 】4 15 24 63
第五趟排序后 【1】3 4 15 24 63
3)算法实现
下面来介绍一下直接选择排序的具体用法。
例如:
在项目中创建类,这个类的代码将作为直接选择排序的一个演示,其中排序使用的是正排序。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
输出结果:
1>3>4>15>24>63
3.反转排序
顾名思义,反转排序就是以相反的顺序把原有数组的内容重新排序,反转排序算法在程序开发中也经常用到。
1)基本思想
反转排序的基本思想比较简单,也很好理解,其实现思路就是把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,依此类推,直到把所有的数组元素反转替换。
2)算法示例
反转排序是对数组两边的元素进行替换,所以只需要循环数组长度的半数次,如数组的长度为7,那么for循环只需要循环3次。
例如:
初始数组资源【10 20 30 40 50 60】
第一趟排序后 60 【20 30 40 50】10
第二趟排序后 60 50 【30 40 】20 10
第三趟排序后 60 50 40 30 20 10
3)算法实现
下面来介绍一下反转排序的具体用法。
例如:
在项目中创建类,这个类的代码将作为反转排序的一个演示。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
输出结果:
数组原有内容:
10 20 30 40 50 60
数组反转后的内容:
60 50 40 30 20 10