1.数组的概念
数组是一种数据结构,用来存储同一类型值的集合,相当于一个容器;
2.数组的特点
定义数组后,会为数组中的元素从0开始编号,这种编号也叫下标,通过这些下标来访问数组中的元素;
一旦创建了数组,就不能再改变它的大小(尽管可以改变数组中的每个元素);
数组中的元素有默认值:
(1).数字数组元素初始化为0;
(2).布尔类型元素初始化为false;
(3).引用类型元素初始化为null;
3.数组的初始化
(1).格式:元素类型[ ] 数组名 = new 元素类型[元素个数或数组长度];
eg:int[ ] arr = new arr[5];//定义一个长度为5的,名为arr的数组;
然后通过数组下标,给数组中的元素赋值;arr[x] = 具体值;
(2).格式:元素类型[ ] 数组名 = new 元素类型[ ]{元素,元素...,元素};
eg:int[ ] arr = new int[ ]{1,3,5,7,9};
注意:在这样定义时:不能指定数组的大小;
int[ ] arr = {2,4,6,8};
4.二维数组
(1).二维数组可以理解为数组中的数组;
(2).定义二维数组的格式:规则数组或不规则数组;
格式一:元素类型[ ][ ] 数组名称 = new 元素类型[二维的维数][一维的维数];
eg:int[ ][ ] arr = new int[3][2];//二维数组中有三个一维数组,每个一维数组中含有两个元素;
格式二:同上述定义方式,但是只指定二维数组的维数,一维数组在分别进行初始化;
eg:int[ ][ ] arr = new int[3][ ];
arr[0] = new int[2];
arr[1] = new int[1];
arr[2] = new int[3];
格式三:在定义的时候初始化;
eg:int[ ][ ] arr = {{1,2,3,4},{5,6,7},{8,9}};
(3).二维数组的内存结构:
5.数组的操作
5.1 数组的获取操作
(1).获取数组的具体元素:利用角标值;特别注意在二维数组中,利用角标获取时,要区分获取的是一维数组的引用还是数组的元素;例如:数组arr[2][2]中,利用arr[0],arr[1]获取的是一维数组的引用,arr[0][0]获取的是数组中的元素;(2).获取数组的长度:数组名称.length; 获取的是属性,不是方法,使用时不要加括号;(3).获取数组元素的最值:
/* 需求:获取数组元素的最值; 分析:可以将获取最值的功能封装为相应的方法; 1.确定返回类型:返回的是数组中的最值元素,那么返回类型为数组元素类型; 2.确定未知参数:获取的是某个数组中的最值,因此数组作为参数传递; */ package com.zr.day04; class ArrTest { public static void main(String[] args) { int[] arr = {3,36,25,41,99,87,76,54}; System.out.println("数组arr中的最大元素为:"+getMax(arr)); System.out.println("数组arr中的最小元素为:"+getMin(arr)); } //方式一:将max初始值定义为数组中的某个元素值;这里定义为端点0角标的元素值; public static int getMax(int[] array) { int max = array[0]; for(int x=1; x<array.length; x++) { if(max<array[x]) max = array[x]; } return max; } //方式二:将min初始值定义为数组元素的角标;这里定义为端点元素的角标0角标; public static int getMin(int[] array) { int min = 0; for(int x=1; x<array.length; x++) { if(array[min]>array[x]) min = x; } return array[min]; } }
5.2 数组的遍历操作
(1).普通的for循环;
使用普通for循环的优点是:在遍历时,可以在遍历的同时,利用数组的角标对遍历的元素进行更多更丰富的操作;
/* 需求:使用普通for循环实现对数组的遍历; 分析:最常用的遍历操作之一就是打印,因此可以将打印数组中的元素封装为一个方法,在以后使用的时候只需要调用这个方法即可; 1.确定功能的返回值类型:打印,没有返回值,void; 2.确定功能的未知参数:因为打印的是数组元素所以将数组作为参数传递为该功能; */ package com.zr.day04; class ArrDemo { //主函数:用来测试打印数组元素功能是否正确; public static void main(String[] args) { int[] arr = {65,91,89,36,42}; printArr(arr); } //打印数组功能的实现; public static void printArr(int[] array) { System.out.print("{"); for(int x=0; x<array.length; x++) { if(x == array.length -1) System.out.println(array[x]+"}"); else System.out.print(array[x]+","); } } }
(2)增强的for循环
增强的for循环格式:for(元素类型 变量名:集合) { 语句 }
其中集合表达式必须是一个数组或者是一个实现了Iterable接口的类对象;
相较于普通的for循环:在语句代码上遍历数组元素显得更加简洁,但是也存在一定的缺陷,比如希望在for循环中只遍历部分元素时,或者希望在for循环中使用具体的角标值时,增强的for循环就不适用了;
package com.zr.day04; class ArrDemo { //使用增强的for循环遍历数组元素; public static void main(String[] args) { int[] arr = {65,91,89,36,42}; for(int x:arr)//此处的x变量用来获取元素值,而不是角标值; { System.out.print(x+" "); } } }
5.3 数组的排序操作
排序的方法有许多种,这里简单介绍选择排序和冒泡排序;(1).选择排序:选取数组中某一位置的元素,同其他各个位置的元素相比较,当满足某条件时,进行位置置换;下一趟操作时在选取另一位置的元素重复此操作,直至每个位置都完成上述操作;
选择排序原理示意图如下:
(2).冒泡排序:冒泡排序是数组中相邻两个元素之间进行比较,当满足条件时,作位置置换,每一趟排序完成后数组中的参与该趟排序的最值会依次向数组的某一段移动;
冒泡排序原理示意图:
(3).分析排序功能的设计:明确返回类型和参数列表;
首先,确定参数列表,因为要对数组进行排序,所以未知参数为数组;
接下来,确定返回类型:
通过上图可知:当将数组作为参数传递给功能中定义的形式参数后,由于数组是引用类型,所以通过形式参数操作的也是数组本身,因此排序功能的返回值类型为void;
(4).两种排序方法的详细设计:
/* 需求:分别实现选择排序和冒泡排序; */ package com.zr.day04; class ArrSortDemo { public static void main(String[] args) { int[] arr1 = {23,34,45,12,9}; int[] arr2 = {9,7,5,4,2,1}; printArr(arr1); selectSort(arr1); printArr(arr1); System.out.println("|-------------------------------"); printArr(arr2); bubbleSort(arr2); printArr(arr2); } public static void selectSort(int[] array) //选择排序 { //array.length-1:当最后一趟中要比较的元素只有一个就不要在进行比较; for(int x=0; x<array.length-1; x++) { //x所在位置为这一趟被选择的位置,x+1:与之进行比较的元素在下一个位置; for(int y=x+1; y<array.length; y++) { if(array[x]>array[y]) { int temp = array[x]; array[x] = array[y]; array[y] = temp; } } } } public static void bubbleSort(int[] array) //冒泡排序 { //array.length-1:当最后一趟中要比较的元素只有一个就不要在进行比较; for(int x=0; x<array.length-1; x++) { //减x:表示已经进行了x趟排序,在末端有x个已经排序完成的元素; //减1:防止y+1出现ArrayIndexOutOfBoundException,数组角标越界异常; for(int y=0; y<array.length-x-1; y++) { if(array[y]>array[y+1]) { int temp = array[y]; array[y] = array[y+1]; array[y+1] = temp; } } } } public static void printArr(int[] array) //打印数组 { System.out.print("{"); for(int x=0; x<array.length; x++) { if(x == array.length -1) System.out.println(array[x]+"}"); else System.out.print(array[x]+","); } } }
5.4 数组元素的置换操作
数组元素的置换操作:发现在排序过程中有许多置换元素的操作,因此可以将这个功能进行封装;确定功能的返回类型:没有返回值,定义为void;确定功能的参数列表:对哪个数组的元素进行置换,具体哪两个位置的元素需要置换;package com.zr.day04; class ArrSwapDemo { public static void main(String[] args) { int[] arr = {1,2,3}; printArr(arr); swap(arr,0,arr.length-1); printArr(arr); } public static void swap(int[] array, int x, int y) { int temp = array[x]; array[x] = array[y]; array[y] = temp; } }
5.5 数组的查找操作
普通查找:可以对无序的数组元素进行查找;效率较低;折半查找:针对有序数组的查找,可以明显提高查找效率;(1).折半查找成功
(2).折半查找失败
详细代码设计:确定返回值类型:当查找成功时,应该返回的是该key值所在的位置或者角标值;当查找失败时,返回的是-1或者是该key值应该插入的位置;确定参数列表:对指定数组进行指定值的查找;/* 实现折半查找; 1,确定返回值类型: 当查找成功时返回的是key值所在的位置或者角标值; 当查找失败时返回的是-1,或者是key值应该插入的位置; 2,确定参数列表:对指定的数组进行指定值的查找; */ package com.zr.day04; class BinSearchDemo { public static void main(String[] args) { int[] arr ={3,12,24,35,45,66,77,88,99}; int key = 22; System.out.println(search(arr,key)); } public static int search(int[] array, int key) { //分别定义两个指针,分别指向数组两个端点; int low = 0; int high = array.length-1; //折半查找的中间值; int mid; while(low<high)//定义循环结束条件 { //每次循环开始时,重新计算中间值; mid = (low+high)/2; //关键字值小于中间值时,高位指针左移; if(key<array[mid]) { high = mid-1; } //关键字值大于中间值时,地位指针右移; else if(key>array[mid]) { low = mid+1; } else return mid;//查找成功 } return -low;//查找失败返回应该插入的位置; } }
6.数组的应用
查表法实现进制之间的转换:
/* 需求:利用数组查表实现数制之间的转换; */ package com.zr.day04; class AppDemo { public static void main(String[] args) { toBin(6); System.out.println(); toHex(60); System.out.println(); toOct(60); } //十进制转换为二进制 public static void toBin(int num) { trans(num,1,1); } //十进制转换为十六进制 public static void toHex(int num) { trans(num,15,4); } //十进制转换为八进制 public static void toOct(int num) { trans(num,7,3); } /* * 调用最底层的转换方法 * 1.返回类型:直接输出打印; * 2.参数列表: * num:从上层调用者接收来的要转换的值; * base:基数,每次移位后与操作值; * offset:移位值; */ private static void trans(int num,int base,int offset) { //判断当给定值为0时,就可以直接输出,然后返回; if(num == 0) { System.out.println(0); return; } //定义表格数组,用来实现角标和字符之间的对应关系; char[] chs = {'0','1','2','3', '4','5','6','7', '8','9','A','B', 'C','D','E','F'}; //临时数组;用来存储临时值,然后按照指定方式输出; //也可以使用StringBuilder,利用字符串对象来存储然后返回; char[] arr = new char[32]; //定义一个指针,用来操作临时数组中的元素; int pos = arr.length; while(num!=0) //定义循环结束条件 { //与操作 int temp = num & base; //存储临时值 arr[--pos] = chs[temp]; //移位操作 num = num >>> offset; } //打印,从有效值开始打印; for(int x=pos; x<arr.length; x++) { System.out.print(arr[x]); } } }
7.数组工具类
在Java体系中提供了专门用来操作数组的工具类:java.util.Arrays;Arrays中定义的都是静态方法,包括一系列非常有用的对数组的操作;