目录
数组是相同类型的、用一个标识符封装到一起的基本类型数据序列或对象序列。
6.1数组概述
数组中的每个元素具有相同的数据类型,在java中同样将数组看做一个对象;虽然基本数据类型不是对象,但是由数据类型组成的数组却是对象。
6.2一维数组的创建和使用
一维数组实质上是一组相同类型数据的线性集合。
6.2.1创建一维数组
数组作为对象允许使用new关键字进行内存分配,在使用数组前,必须首先定义数组变量所属的类型。一维数组的创建有两种形式:
(1)先声明,再用new操作符进行内存分配
声明一维数组有下列两种方式:
数组元素类型决定了数组的数据类型,它可以是java中任意的数据类型;数组名字为一个合法的标识符,符号"[ ]"指明该变量为一个数组类型变量,单个"[ ]"表示创建的数组为一维数组。
声明数组后并不能立即访问数组的任何元素,因为声明数组只是给出了数组名字和元素的数据类型,要想真正使用数组,还要为它分配内存空间。在为数组分配内存空间时必须指明数组的长度。内存分配的语法如下:
在使用new关键字分配内存时,必须指定数组元素的数据类型和个数,即数组的长度。
以上代码表示要创建一个有5个元素的整型数组,并将创建的数组对象赋给引用变量arr,即引用变量arr引用这个数组.
注意,数组的下标是从0开始的;在使用new为数组分配内存时,整型数组中的各个元素的初始值都是0.
2.声明的同时为数组分配内存
语法如下:
这种格式是java中推荐的。
6.2.2初始化一维数组
数组的初始化可以分别初始化数组中的每个元素,数组的初始化方式有两种:
数组的初始化就是包括在大括号之内用逗号分开的表达式列表,用逗号分隔开数组的每个元素,系统自动为数组分配一定的空间。
6.2.3使用一维数组
6.3二维数组的创建和使用
如果一维数组的各个元素任然是一个数组,那么它就是一个二维数组。二维数组的第一个下标表示元素所在的行,第二个下标表示元素所在的列。
6.3.1二维数组的创建
二维数组的创建同样有两种方式:
(1)先声明,再用new操作符进行内存分配
声明二维数组的语法如下:
同一维数组一样,二维数组在声明时也没有分配内存,同样要使用new来分配内存空间,然后才可以访问数组元素。对于高维数组,有两种为数组分配内存的方式:
【1】直接为每一维分配内存空间
【2】分别为每一维分配内存
2.声明的同时为数组分配内存
使用这种方式为数组分配内存时,首先指定最左边维数的内存,然后再给余下的维数分配内存。
6.3.2二维数组初始化
二维数组的初始化与一维数组一样,都可以使用大括号完成。语法如下:
初始化二维数组后,要明确数组的下标都是从0开始的。
6.3.3使用二维数组
对于整型二维数组,创建成功后系统会赋给数组中的每个元素初始值为0.
6.4数组的基本操作
java.util包的Arrays类包含了用来操作数组的各种方法。
6.4.1遍历数组
遍历数组一般都是用for循环来实现。
在遍历数组时,使用foreach语句会更简单。
6.4.2填充替换数组元素
数组中的元素定义完成后,可以通过Arrays类的静态方法fill()来对数组中的元素进行替换。该方法经过多种重载形式可以完成任意类型数组元素的替换。fill()方法有两种参数类型:
(1)fill(int[] a,int value) 将指定的值分配给数组的每个元素,语法如下:
(2)fill(int[] a,int fromIndex,int toIndex,int value) 将指定的值分配给数组指定范围内的元素,填充的范围从fromIndex~toIndex-1;如果fromIndex=toIndex,则填充的范围为空;注意索引的大小不能大于数组的长度,否则会报错。语法如下:
6.4.3对数组进行排序
通过Arrays类的静态方法sort()可以实现对数组的排序。sort()方法提供了多种重载形式,可对任意类型的数组进行升序排序。语法如下:
java中对String类型的数组排序算法是根据字典顺序排序的,因此数字排在字母前面,大写字母排在小写字母前面。
6.4.4复制数组
Arrays类的copyOf()方法与copyOfRange()方法可以实现对数组的复制,前者是复制数组到指定长度,后者则是将数组中指定范围内的元素复制到一个新数组中。
(1)copyOf()
语法如下:
(2)copyOfRange()
语法如下:
6.4.5数组查询
Arrays类的binarySearch()方法,使用二分法来搜索指定数组,以获得指定对象,方法的返回值为搜索元素的索引。方法提供了多种重载形式:
(1)binarySearch(Object[] a,Object key)
语法如下:
如果key包含在数组中,则返回搜索值的索引,否则返回-1或"-"(插入点)。插入点是搜索键将要插入数组的那一点,即第一个大于此键的元素索引。
上面代码中变量index的值是元素"8"在数组arr中索引在0~1内的索引位置。由于在指定的范围内不存在元素"8",index的值是"-"。如果对数组进行排序,元素8应该在25前面,因此插入点应该是25的索引值,所以index的值是-2.
如果元素中的所有值都小于指定的键,则index为a.length。
注意,在进行数组查询之前要进行排序(使用sort()方法)。如果没有对数组进行排序,则结果是不确定的,因为如果数组中带有多个指定值的元素,则无法保证找到的是哪一个。
返回值为1是对数组排序后元素4的索引位置;
(2)binarySearch(Object[] a,int fromIndex,int toIndex,Object key) 该方法在指定范围内检索某个元素,语法如下:
如果范围中所有的值都小于指定的键,则返回值为toIndex。
6.5数组排序算法
6.5.1冒泡排序
冒泡排序是最常用的数组排序算法之一,它排序数组元素的过程总是将小数往前放、大数往后放,类似水中气泡往上上升的动作,所以叫做冒泡排序。
(1)基本思想
冒泡排序的基本思想是比对相邻的元素值,如果满足条件就交换元素值,把较小的元素移到数组前面,把较大的元素移到数组后面,也就是交换两个元素的位置,这样较小的元素就会持续上升到顶部。
(2)算法示例
冒泡排序由双层循环实现,其中外层循环用于控制排序轮数,一般为要排序的数组长度减1,因为最后一次循环只剩下一个数组元素,不需要比对。而内层循环主要用于比对每个临近元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少。例如,一个拥有6个元素的数组:
第一轮外层循环时把最大的元素值63移到了最后面,第二轮外层循环就不需要再比对最后一个元素63了;下一次循环将24放在了63的前一个位置,其他循环依次类推,继续完成排序任务。
(3)算法实现
public class Bubblesort {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建一个数组,这个数组元素是乱序的
int[] array= {64,23,12,4,97,65,29};
//建立冒泡排序类的对象
Bubblesort sorter=new Bubblesort();
//调用排序方法将数组排序
sorter.sort(array);
}
//冒泡排序
public void sort(int[] array) {
for(int i=1;i<array.length;i++) {//外层循环次数为array.length-1
//比较两个相邻的元素,较大的数往后冒泡
for(int j=array.length-1;j>i-1;j--) {
if(array[j]>array[j-1]) {
int temp=array[j];
array[j]=array[j-1];
array[j-1]=temp;//交换两个元素的位置
}
}
}
showarray(array);//输出冒泡排序后的元素
}
public void showarray(int[] array) {
for(int i:array) {//遍历数组
System.out.println(i);
}
}
}
6.5.2直接选择排序
直接选择排序属于选择排序的一种,它的排序速度要比冒泡排序快一些。
(1)基本思想
选择排序的基本思想是将指定位置与其他元素分别对比,如果满足条件就交换元素值,注意这里区别冒泡排序,不是交换相邻元素,而是把满足条件的元素与指定排序位置交换(如从最后一个元素开始排序),这样排序好的位置逐渐扩大,直至整个数组排好序。
这就好比从包含数字1~10的乱序数字堆中分别选择合适的数字,组成一个从1~10的排序,而首先从数字堆中选出1放在第1位,然后选出2(注意此时数字堆中已经没有1了)放在第2位,直到找到数字9放在8的后面,最后剩下10,直接放到最后就行了。
与冒泡排序相比,直接选择排序的交换次数少一些,所以速度快一些。
(2)算法示例
每一趟从待排序的数据元素中选择出最小(或最大)的一个元素,放在已经排好序的数列的最后,直到全部待排序的数据排完。
(3)算法实现
public class Seclectsort {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建一个数组,这个数组元素是乱序的
int[] array= {97,127,3,26,78,43,23};
//创建直接排序类的对象
Seclectsort sorter=new Seclectsort();
//调用排序对象的方法将数组排序
sorter.sort(array);
}
//直接选择排序法
public void sort(int[] array) {
int index;
for(int i=1;i<array.length;i++) {
index=0;
for(int j=1;j<=array.length-i;j++) {
if(array[j]>array[index]) {
index=j;//获取数列最大数的索引
}
}
//交换位置array.length-i和index上的两个数
int temp=array[array.length-i];
array[array.length-i]=array[index];
array[index]=temp;
}
showarray(array);
}
public void showarray(int[] array) {
for(int i:array) {
System.out.println(i);
}
}
}
6.5.3反转排序
反转排序就是以相反的顺序把原有数组的内容重新排序。
(1) 基本思想
反转排序的基本思想就是把数组的最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,以此类推,直到把所有数组元素反转替换。
(2)算法示例
反转排序只是对数组两边的元素进行替换,所以只需要循环数组长度的半数次。
(3)算法实现