4.1数组的概述
数组第具有相同数据类型的一组数据的集合,例如,球类的集合--足球、篮球、羽毛球等;器集合--电视机、洗衣机、电风扇等。在程序设计中,可以将这些集合称为数组。数组中的每个元素具有相同的数据类型。在 Java 中同样将数看作是一个对象,虽然基本数据类型不是对象由基本数据类型组成的数组则是对象。在程序设计中引入数组可以更有效地管理和处理数据。我们经常使用的数组包括一维数组和二维数组等。
4.2一维数组
一维数组实质上是一组相同类型数据的线性集合,例如学校中学生们排列的一字长队就是一个数组,每一位学生都是数组中的一个元素。再比如快捷酒店,就相当于一个一维数组,每一个房间都是这个数组中的元素。当在程序中需要处理一组数据,或者传递一组数据时,就可以使用数组实现。
4.2.1创建一维数组
数组元素类型决定了数组的数据类型。它可以是Java中任意的数据类型,包括基本数据类型和其他引用类型。数组名字为一个合法的标识符,符号“[ ]”指明该变量是一个数组类型变量。单个“[ ]”表示要创建的数组是一个一维数组。
4.2.2初始化一维数组
数组可以与基本数据类型一样进行初始化操作,也就是赋初值。数组的初始化可分别初始化数组中的每个元素。
1、int[] a = new int[]{1,2,3,4,5},
2、int[] a;
a = {1,2,3,4,5};
3、int[] a = new int[5];
a[0] = 1;
a[1] = 2;
a[2] = 3;
a[3] = 4;
a[4]= 5;
4.2.3获取数组长度
我们初始化一维数组的时候都会在内存中分配内存空间,内存空间的大小决定了一维数组能够存储多少个元素,也就是数组长度。如果我们不知道数组是如何分配内存空间的,该如何获取数组长度呢?我们可以使用数组对象自带的length属性。
例4.1 使用length属性获取数组长度。
public class GetArrayLength1 {//创建主类
public static void main(String[] args) {//主方法
// TODO Auto-generated method stub
char a[] = { 'A', 'B', 'c', 'D' }; // 创建一维数组
System.out.println("数组a的长度为"+a.length); //输出结果
char b[] =a; //创建一维数组b,直接等于数组a
System.out.println("数组b的长度为"+b.length);//输出结果
}
}
结果
4.2.4使用一维数组
在Java中,一维数组是最常见的一种数组结构。
例4.2 在项目中创建类GetDay,在主方法中创建int型数组,并实现将各月的天数输出。
public class GetDay2 {//创建主类
public static void main(String[] args) {//主方法
int day[] = new int[] { 31,28,31,30,31,30,31,31,30,31,30,31}; //创建并初化一维组
for (int i = 0; i <12; i++) {//利用循环将信息输出
System.out.println((i+1)+"月有"+day[i]+"天");//输出的信
}
}
}
结果
4.3二维数组
4.3.1创建二维数组
4.3.2初始化二维数组
例4.3 分别用三种方法初始化二维数组。
public class IntTDArray3 {//创建主类
public static void main(String[] args) {//主方法
// TODO Auto-generated method stub
/*第一种方式*/
int tdarr1[][] = { { 1, 3, 5 },{ 5, 9, 10 } };//定义int 型数组tdarr1
/*二种方式*/
int tdarr2[][] = { { 65, 55, 12 },{ 92, 7, 22 } };//定义int 型数组tdarr2
/*第三种方式*/
int tdarr3[][] = new int[2][3]; // 先给数组分配内存空间
tdarr3[0] = new int [] {6, 54, 71};//给第一行分配一个一维数组
tdarr3[1][0] = 63; //给第二行第一列赋值为63
tdarr3[1][1] = 10;//给第二行第二列赋值为10
tdarr3[1][2] = 17;//给第二行第三列赋值为7
}
}
4.3.3使用二维数组
二维数组在实际应用中非常广泛。
例4.4 创建一个二维数组,将古诗《春晓》的内容赋值于二维数组,然后分别用横版和竖版两种方式输出。
public class Poetry4 {//创建主类
public static void main(String[] args) {//主方法
// TODO Auto-generated method stub
char arr[][] = new char[4][]; // 创建一个4行的二维数组
arr[0] = new char[] { '春','眠','不','觉','晓'}; // 为每一行赋值
arr[1] =new char[] { '处','处','闻','啼','鸟'}; //赋值
arr[2] = new char[] { '夜','来','风','语','声'}; //赋值
arr[3] = new char[] { '花','落','知','多','少' };//赋值
/*横版输出*/
System.out.println("---横版---");//输出结果
for (int i = 0; i < 4; i++) {// 循环4行
for( int j=0;j < 5;j++){//循环5列
System.out.print(arr[i][j]);//输出数组中的素
}
if (i % 2 == 0) {//循环语句
System.out.println(",");//如果是一、三句,输出号
}else {//i%2!=0
System.out.println("。");//如果是二、四句,输出句号
}
}
/*竖版输出*/
System.out.println("\n-----竖版-----"); //输出结果
for (int j = 0; j < 5; j++) {// 列变行
for (int i = 3; i >=0; i--) {// 行变列,反序输出
System.out.print(arr[i][j]);//输出数组中的元素
}
System.out.println();//换行
}
System.out.println("。,。,");//输出最后的标点
}
}
结果
例4.5 创建一个不规则二维数组,输出数组每行的元素个数及各元素的值。
public class IrregularArray5 {//创建主类
public static void main(String[] args) {//主方法
// TODO Auto-generated method stub
int a[][] = new int[3][];//创建二维数组,指定行数,不指定列数
a[0] = new int[] { 52, 64, 85, 12, 3, 64};//第一行分配6个元素
a[1] = new int[] { 41, 99, 2 };//第二行分配3个元素
a[2] = new int[] { 285, 61, 278, 2 };//第三行分配4个元素
for (int i = 0; i < a.length; i++) {//外循环
System.out.print("a[" + i + "]中有" + a[i].length + "个元素,分别是: ");
for (int tmp : a[i]){ // foreach 循环输出数组中元素
System.out.print(tmp +" ");//输出结果
}
System.out.println();//输出结果
}
}
}
结果
4.4数组的基本操作
1.shift() 方法:把数组的第一个元素删除,并返回第一个元素的值 2.concat() 方法:用于连接两个或多个数组,并返回一个新数组,新数组是将参数添加到原数组中构成的。
3. join() 方法:用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。4. pop() 方法:用于删除并返回数组的最后一个(删除元素)元素,如果数组为空则返回undefined ,把数组长度减 1。
5.push() 方法:可向数组的末尾添加一个或多个元素,并返回新的长度,(用来改变数组长度)。6.reverse() :方法用于颠倒数组中元素的顺序。
7.slice() 方法:可从已有的数组中返回选定的元素。slice(开始截取位置,结束截取位置)。
4.4.1遍历数组
遍历数组就是获取数组中的每个元素。通常遍历数组都是使用for循环来实现的。遍历一维数组很简单,也很好理解,下面详细介绍遍历二维数组的方法。
遍历二维数组需使用双层for循环,通过数组的length属性可获得数组的长度。
例4.6 定义二维数组,实现将二维数组中的元素呈梯形输出。
public class Trap6 {//创建主类
public static void main(String[] args) {//主方法
// TODO Auto-generated method stub
int b[][] = new int[][] { { 1 }, { 2, 3 }, { 4, 5, 6 } }; // 定义二维数组
for (int k = 0; k < b.length; k++) {//外循环
for (int c = 0;c < b[k].length;c++){ //循环遍历二维数组中的每个元素
System.out.print(b[k][c]); //将数组中的元素输出
}
System.out.println();//输出换行
}
}
}
结果
4.4.2填充和批量替换数组元素
数组中的元素定义完成后,可通过Arrays类的静态方法fill()来对数组中的元素进行分配,可以起到填充和替换的效果。fill()方法有两种参数类型,下面以int型数组为例介绍fill()方法的使用。
1、fill(int[]a,int value)
该方法可将指定的int值分配给int型数组的每个元素
例4.7 通过fill()方法填充数组,最后将数组中的各个元素输出。
import java.util.Arrays; //导入java.util.Arrays类
public class Swap7 {//创建主类
public static void main(String[] args) {//主方法
// TODO Auto-generated method stub
int arr[] = new int[5];//创建int型数组
Arrays.fill(arr, 8); // 使用同一个值对数组进行填充
for (int i = 0; i < arr.length; i++) {// 循环遍历数组中的元素
//将数组中元素依次输出
System.out.println("第"+i+"个元素是:"+arr[i]);//输出结果
}
}
}
结果
2、fill(int[]a,int fromIndex,int tolndex,int value)
该方法可将指定的int值分配给int型数组指定范围中的每个元素。填充的范围从索引fromIndex(包括)一直到索引tolndex(不包括)。如果,则填充范围为空。
例4.8 通过fill()方法替换数组元素,最后将数组中的各个元素输出。
import java.util.Arrays; //导入java.util.Arrays类
public class Displace8 {//创建主类
public static void main(String[] args) {//主方法
// TODO Auto-generated method stub
int arr[] = new int[] { 45, 12, 2, 77, 31, 91, 10 };// 定义并初始化 int 型数组arr
Arrays.fill(arr,1, 4,8); //使用fill()方法对数组进行填充
for (int i = 0; i < arr.length; i++) {//循环遍历数组中的元素
//将数组中的元素输出
System.out.println("第" + i + "个元素是:" + arr[i]);//输出结果
}
}
}
结果
4.4.3复制数组
Arrarys 类的 copyOf()方法与copyOfRange()方法可实现对数组的复制。copyOf()方法是复制数组至指定长度,copyOfRange()方法则将指定数组的指定长度复制到一个新数组中。
1.copyOf()方法
该方法提供了多种使用方式,用于满足不同类型数组的复制。语法如下: Arrays.copyOf(arr,int newlength)
例4.9 创建一维数组,将此数组复制得到一个长度为5的新数组,并将新数组输出。
import java.util.Arrays; //导入java.util.Arrays类
public class Cope9 {//创建主类
public static void main(String[] args) {//主方法
// TODO Auto-generated method stub
int arr[] = new int[] { 23, 42, 12 };// 定义数组
int newarr[]=Arrays.copyOf(arr, 5); //复制数组arr
for (int i = 0; i < newarr.length; i++) {//循环变量复制后的新数组
System.out.println("第" + i + "个元素是:" + newarr[i]); //将新数组输出
}
}
}
结果
2.copyOfRange()方法
该方法提供了多种使用方式。其常用语法如下:
Arrays.copyOfRange(arr,int formIndex,int toIndex) arr:
例4.10 创建一维数组,并将数组中索引位置是0~3之间的元素复制到新数组中,最后将新数组输出。
import java.util.Arrays; //导入java.util.Arrays类
public class Repeat10 {//创建主类
public static void main(String[] args) {// 主方法
int arr[] = new int[] { 23, 42, 12, 84, 10 }; // 定义数组
int newarr[] = Arrays.copyOfRange(arr, 0, 3); // 复制数组
for (int i =0; i < newarr.length; i++){ //循环遍历复制后的新数组
System.out.println(newarr[i]);// 将新数组中的每个元素输出
}
}
}
结果
4.5 数组的排序
在程序设计中,经常需要将一组数据进行排序,这样更加方便统计与查询。程序常用的排序方法有冒泡排序、选择排序等。
4.5.1 算法:冒泡排序
冒泡排序是最常用的数组排序算法之一,它以简洁的思想与实现方法备受青睐,是初学者最先接触的一个排序算法。使用冒泡排序时,排序数组元素的过程总是小数往前放,大数往后放,类似水中气泡往上升的动作,所以称作冒泡排序。
基本思想
冒泡排序的基本思想是对比相邻的元素值,如果满足条件就交换元素值,把较小的元素移动到
数组前面,把较大的元素移动到数组后面(也就是交换两个元素的位置),这样较小的元素就像气
泡一样从底部上升到顶部。
例4.11 在项目中创建BubbleSort类,这个类的代码将实现冒泡排序的一个演示,其中排序使用的是正排序。
public class BubbleSort11 {//创建主类
/**
* 冒泡排序方法
*
* @param array
* 要排序的数组
*/
public void sort(int[] array) { //主函数
for (int i = 1; i < array.length; i++) {//比较相邻两个元素,较大的数往后冒泡
for (int j = 0; j < array.length - i; j++){//循环要求
if(array[j] > array[j + 1]) {//如果前一个元素比后一个元素大,则两元素互换
int temp = array[j]; // 把第一个元素值保存到临时变量中
array[j] = array[j+1];//把第二个元素值保存到第一个元素单元中
array[j + 1] =temp; // 把临时变量(也就是第一个元素原值)保存到第二个元素中
}
}
}
showArray(array);//输出冒泡排序后的数组元素
}
/**
* 显示数组中的所有元素
*
* @param array
* 要显示的数组
*/
public void showArray(int[] array) {//主方法
System.out.println("冒泡排序的结果:");// 输出结果
for (int i :array) { // 遍历数组
System.out.print(i + " ");//输出每个数组元素值
}
System.out.println();//输出结果
}
public static void main(String[] args) {//主方法
//创建一个数组,这个数组元素是乱序的
int[] array={63, 4, 24, 1, 3, 15 };//创建排序类的对象
BubbleSort11 sorter=new BubbleSort11();//存放代码的文件名
sorter.sort(array);//调用排序方法数组排序
}
}
结果
4.5.2算法:选择排序
直接选择排序方法属于选择排序的一种,它的排序速度要比冒泡排序快一些,也是常用的排序 算法,是初学者应该掌握的。
基本思想
直接选择排序的基本思想是将指定排序位置与其他数组元素分别对比,如果满足条件就交换元素值,注意这里区别冒泡排序,不是交换相邻元素,而是把满足条件的元素与指定的排序位置交换(如从最后一个元素开始排序),这样排序好的位置逐渐扩大,最后整个数组都成为已排序好的格式。
这就好比有一个小学生。从包含数字 1~10的乱序的数字堆中分别选择合适的数字。组成一个从1~10的排序。而这个学生首先从数字堆中选出1,放在第一位;然后选出2(注意这时数字堆中已经没有1了),放在第二位,依此类推,直到找到数字 9,放到8的后面,最后剩下10,就不用选择了,直接放到最后就可以了。
与冒泡排序相比,直接选择排序的交换次数要少很多,所以速度会快些。
例4.12 在项目中创建SelectSort类,这个类的代码将作为直接选择排序的一个演示,其中排序使用的是正排序。
public class SelectSort {//创建主类
/**
* 直接选择排序法
* @param array
* 要排序的数组
*/
public void sort(int[] array) {//主函数
int index;//整数索引
for (int i = 1; i <array.length; i++) {//比较相邻两个元素,较大的数往后冒泡
index = 0;//给index赋值
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);//输出直接选择排序后的数组值
}
/**
* 显示数组中的所有元素
* @param array
* 要显示的数组
*/
public void showArray(int[] array) {//主函数
System.out.println("选择排序的结果为:"); //输出结果
for (int i : array) { //遍历数组
System.out.print(i + " ");//输出每个数组元素值
}
System.out.println();//输出结果
}
public static void main(String[] args) {//主方法
//创建一个数组,这个数组元素是乱序的
int[] array = { 63, 4, 24, 1, 3, 15 }; //创建直接排序类的对象
SelectSort sorter = new SelectSort();//存放代码的文件名
sorter.sort(array);//调用排序对象的方法将数组排序
}
}
结果
4.5.3Arrays.Sort()方法
通过类的静态方法可实现对数组的排序。方法提供了多种使用方式,可对任意类型数组进行升序排序。语法如下:
Arrays.Sort(object)
例4.13 创建一维数组,并将数组排序后输出。
import java.util.Arrays; //导入java.util.Arrays类
public class Taxis13 {//创建主类
public static void main(String[] args) { // 主方法
int arr[] = new int[] { 23, 42, 12, 8 }; // 声明数组
Arrays.sort(arr);//将数组进行排序
System.out.println("排序后的结果为");//输出结果
for (int i =0; i < arr.length; i++){ //循环遍历排序后的数组
System.out.print(arr[i]+" ");//将排序后数组中的各个元素输出
}
}
}
结果