版权声明:此文章转载自_infocool
原文链接:http://www.infocool.net/kb/Java/201610/206002.html
如需转载请联系听云College团队成员小尹 邮箱:yinhy#tingyun.com
今天学习的内容是数组和Arrays类
一维数组和Arrays类
数组是相同类型的一组数据的集合,数组中元素的类型可以是基本数据类型或者引用类型,数组是对象。Arrays类属于Java核心类库java.util,它包含一套操作数组的静态方法。
数组和容器类的区别有三方面:效率、类型安全和保存基本类型的能力。随着泛型和自动包装机制的出现,容器类已经可以实现类型安全,并且也可以持有基本数据类型。目前数组的优势只剩下效率,但是为效率所付出的代价是数组对象的大小被固定,在其生命周期不能改变。除非证明性能成为问题,并且使用数组会对性能提高有所帮助,否则建议“优选容器而不是数组”。
那为什么我们要学习数组呢?当然是为了面试啦大笑 当然一些常用算法的思想我们也是必须要了解的~
定义一维数组的格式有三种:
数组元素类型[] 数组名=new 数组元素类型[数组元素个数];数组名[0]=值;(可以不初始化,数组中的元素默认初始化)
数组元素类型[] 数组名=new 数组元素类型[]{数组元素}; 注意:这种定义方法不能写数组元素个数
数组元素类型[] 数组名={数组元素} 注意:这种定义方法虽然没用new,但是创建的数组也是对象
使用数组还需要注意:当访问数组不存在的下标,运行时会发生ArrayIndexOutOfBoundsException异常;当数组引用没有引用实体,还在用其操作实体,运行时会发生NullPointerException异常。不过这两种异常不会被编译器发现,它们属于运行时异常(Runtime Exception)。
定义一维数组、使用常规算法和Arrays类静态方法完成对一维数组的遍历排序等操作的示例代码如下:
public class Test18 { public static void main(String[] args){ //第一种定义格式: int[] arr_1=new int[3]; arr_1[0]=1; arr_1[1]=2; arr_1[2]=3; System.out.println(arr_1);//打印引用的值,对象类型+@+数组对象的内存地址 System.out.println(Arrays.hashCode(arr_1));//哈希值 System.out.println(Arrays.toString(arr_1));//使用Arrays类的toString静态覆盖方法将数组转为字符串格式,[1,2,3] //第二种定义格式: int[] arr_2=new int[]{4,5,6}; System.out.println(arr_2);//打印引用的值,对象类型+@+数组对象的内存地址 System.out.println(Arrays.hashCode(arr_2));//哈希值 System.out.println(Arrays.toString(arr_2));//使用Arrays类的toString静态覆盖方法将数组转为字符串格式,[4,5,6] //第三种定义格式: int[] arr_3={7,8,9}; System.out.println(arr_3);//打印引用的值,对象类型+@+数组对象的内存地址 System.out.println(Arrays.hashCode(arr_3));//哈希值 System.out.println(Arrays.toString(arr_3));//使用Arrays类的toString静态覆盖方法将数组转为字符串格式,[7,8,9] //数组常用操作1:遍历
System.out.print("使用for循环遍历一维数组:"); for(int i=0;i<arr_1.length;i++){ System.out.print(arr_1[i]+" ");//1 2 3 } System.out.print("\n使用foreach循环遍历一维数组;"); for(int x:arr_1){ System.out.print(x+" ");//1 2 3 } //数组常用操作2:获取最值 int[] arr_4={3,5,1,6,2,43,35,2,9}; //比较每个元素 int maxElement=arr_4[0]; for(int i=1;i<arr_4.length;i++){ maxElement=(maxElement>arr_4[i])?maxElement:arr_4[i]; } System.out.println("\n数组最大值为"+maxElement);//43 int minElement=arr_4[0]; for(int i=1;i<arr_4.length;i++){ minElement=(minElement<arr_4[i])?minElement:arr_4[i]; } System.out.println("数组最小值为"+minElement);//1 //通过下标比较每个元素 int maxIndex=0; for(int i=1;i<arr_4.length;i++){ arr_4[maxIndex]=(arr_4[maxIndex]>arr_4[i])?arr_4[maxIndex]:arr_4[i]; }
System.out.println("数组最大值为"+arr_4[maxIndex]);//43 int minIndex=0; for(int i=1;i<arr_4.length;i++){ arr_4[minIndex]=(arr_4[minIndex]<arr_4[i])?arr_4[minIndex]:arr_4[i]; } System.out.println("数组最小值为"+arr_4[minIndex]);//1 //借用Arrays类的sort静态方法排序,然后获取最值 Arrays.sort(arr_4); System.out.println("数组最大值为"+arr_4[arr_4.length-1]);//43 System.out.println("数组最小值为"+arr_4[0]);//1 //数组常用操作3:排序 int[] arr_5={3,5,6,4,2,1,8,9,7}; //使用Arrays的sort静态方法(实际开发使用) Arrays.sort(arr_5); System.out.println("使用Arrays静态方法排序的结果:"+Arrays.toString(arr_5));//[1-9] //选择排序 for(int i=0;i<arr_5.length-1;i++){ for(int j=i+1;j<arr_5.length;j++){ if(arr_5[i]>arr_5[j]){ int temp=arr_5[i]; arr_5[i]=arr_5[j]; arr_5[j]=temp; } } }
System.out.println("使用选择排序的结果:"+Arrays.toString(arr_5));//[1-9] //冒泡排序(内循环-1:为了避免下标越界 内循环-i:为了每当外循环增加一次,内循环参与比较的元素个数就递减) for(int i=0;i<arr_5.length-1;i++){ for(int j=0;j<arr_5.length-1-i;j++){ if(arr_5[j]>arr_5[j+1]){ int temp=arr_5[j]; arr_5[j]=arr_5[j+1]; arr_5[j+1]=temp; } } } System.out.println("使用冒泡排序的结果:"+Arrays.toString(arr_5));//[1-9] //数组常用操作4:查找某元素的索引 int[] arr_6={3,1,4,65,7,1}; //遍历查找 for(int i=0;i<arr_6.length;i++){ if(arr_6[i]==1){ System.out.println("数字1在数组中的索引为:"+i);//1 5 } } //使用Arrays类的binarySearch静态方法,本质就是二分法 //使用此方法必须先对数组排序,如果数组未排序将产生不可预料的后果 //如果数组中有多个该值,则无法保证找到的是哪一个 //如果数组没有这个值,那么就会返回这个值在数组中按顺序应该存在的位置取负数再减一 //binarySearch方法还可以限定查找索引范围(第一个包括,第二个不包括) Arrays.sort(arr_6);
System.out.println("数字3在数组中的索引为:"+Arrays.binarySearch(arr_6, 3));//2 System.out.println("数字1在数组中的索引为:"+Arrays.binarySearch(arr_6, 1));//0(实际上有0和1) System.out.println("数字5在数组中的索引为:"+Arrays.binarySearch(arr_6, 5));//-5(-4-1) System.out.println("数字1在数组中的索引为:"+Arrays.binarySearch(arr_6,0,1,1));//0 //数组常用操作5:填充替换数组元素 //使用Arrays的fill静态方法 //可以选择全部填充也可以设定填充范围(第一个包括,第二个不包括) int[] arr_7={1,1,1}; Arrays.fill(arr_7, 2); System.out.println(Arrays.toString(arr_7));//[2,2,2] Arrays.fill(arr_7,0,2,3); System.out.println(Arrays.toString(arr_7));//[3,3,2] //数组常用操作6:复制数组 //使用Arrays的copyOf静态方法 //如果复制长度大于原数组长度,用该类型的默认值填充;如果复制长度小于原数组长度,就从数组的第一个元素开始截取 int[] arr_8={1,2,3,4}; System.out.println(Arrays.toString(Arrays.copyOf(arr_8, 2)));//[1,2] System.out.println(Arrays.toString(Arrays.copyOf(arr_8, 5)));//[1,2,3,4,0] //数组常用操作7:数组间的比较 //Arrays类的equals静态覆盖方法可以比较两个数组的内容(元素个数和元素对应内容) int[] a={1,2,3}; int[] b={1,2,3}; int[] c=new int[]{1,2,3}; int[] d=new int[]{1,2,3};
System.out.println("==和equals的数组验证:"); System.out.println(a==b);//false System.out.println(a.equals(b));//false System.out.println(Arrays.equals(a, b));//true System.out.println(c==d);//false System.out.println(c.equals(d));//false System.out.println(Arrays.equals(c, d));//true } }
细心地人比如我害羞已经发现了一些疑问:引用类型和对象是什么?和基本数据类型有何不同?哈希值和内存地址是什么?为什么使用两种方式得到的哈希值不同?为什么数组使用==和equals会得到false,而使用Arrays的equals方法又能得到true?这些疑问将在之后的几篇文章中详细解答(脑细胞死了好多抓狂)
二维数组
说完了一维数组,二维数组就比较简单了。与一维数组的不同主要就是定义格式和三个Arrays类针对多维数组操作的静态方法,直接看示例程序:
public class Test19 { public static void main(String[] args){ //第一种定义格式 int[][] arr_1=new int[2][3];//数组所有元素有默认值0 System.out.println("使用for循环遍历二维数组:"); for(int i=0;i<arr_1.length;i++){ for(int j=0;j<arr_1[i].length;j++){ System.out.print(arr_1[i][j]+" "); } System.out.println(); } System.out.println("使用foreach循环遍历二维数组;"); for(int[] x:arr_1){ for(int y:x){ System.out.print(y+" "); } System.out.println(); } System.out.println(arr_1);//打印引用的值,对象类型+@+数组对象的内存地址 System.out.println(arr_1.hashCode());//哈希值,与上面的引用的值不同 System.out.println(Arrays.deepHashCode(arr_1));//哈希值,与上面的引用的值不同 System.out.println(arr_1[0]);//打印引用的值,对象类型+@+数组对象的内存地址 System.out.println(arr_1[1]);//打印引用的值,对象类型+@+数组对象的内存地址 //第二种定义格式 int[][] arr_2=new int[2][]; System.out.println(arr_2);//打印引用的值,对象类型+@+数组对象的内存地址(哈希值)
System.out.println(arr_2[0]);//null System.out.println(arr_2[1]);//null //!arr_2[0]={1,2,3};注意这是错误的! arr_2[0]=new int[3]; arr_2[1]=new int[]{4,5,6}; System.out.println(Arrays.deepToString(arr_2));//打印多维数组的Arrays类的静态方法 //第三种定义格式 int[][] arr_3=new int[][]{{1,2,3},{4,5,6}}; //int[][] arr_3={{1,2,3},{4,5,6}};也是可以的 for(int i=0;i<arr_3.length;i++){ for(int j=0;j<arr_3[i].length;j++){ System.out.print(arr_3[i][j]+" "); } System.out.println(); } System.out.println(arr_3);//打印引用的值,对象类型+@+数组对象的内存地址(哈希值) System.out.println(arr_3[0]);//打印引用的值,对象类型+@+数组对象的内存地址(哈希值) System.out.println(arr_3[1]);//打印引用的值,对象类型+@+数组对象的内存地址(哈希值) //二维数组间的比较 int[][] arr_4={{1,2},{3,4}}; int[][] arr_5={{1,2},{3,4}}; int[][] arr_6=new int[][]{{1,2,3},{4,5,6}}; int[][] arr_7=new int[][]{{1,2,3},{4,5,6}}; System.out.println(arr_4==arr_5);//false System.out.println(arr_4.equals(arr_5));//false
System.out.println(Arrays.deepEquals(arr_4, arr_5));//true System.out.println(arr_6==arr_7);//false System.out.println(arr_6.equals(arr_7));//false System.out.println(Arrays.deepEquals(arr_6, arr_7));//true } }