学习笔记之JavaSE(6)--Java基础语法5

来源:互联网 发布:刘斐和郭汝瑰 知乎 编辑:程序博客网 时间:2024/05/16 07:52

今天学习的内容是数组和Arrays类


一、一维数组和Arrays类

数组是存放相同类型的一组数据的容器,它可以存储基本数据类型和对象。比较特殊的是:数组是对象。Arrays类属于Java核心类库java.util,它包含一套操作数组的静态方法。

数组和集合类都作为存放数据的容器,那它们有什么区别呢?数组和集合类的区别有三方面:效率类型安全保存基本类型的能力。随着泛型和自动打包机制的出现,集合类已经可以实现类型安全,并且也可以存储基本数据类型。目前数组的优势只剩下效率,但是为效率所付出的代价是数组对象的大小被固定,在其生命周期不能改变。除非证明性能成为问题,并且使用数组会对性能提高有所帮助,否则建议“优选集合而不是数组”。

那为什么我们要学习数组呢?当然是为了面试啦大笑 当然一些常用算法的思想我们也是必须要了解的

定义一维数组的格式有三种:

  • 数组元素类型[] 数组名=new 数组元素类型[数组元素个数];数组名[0]=值;(可以不初始化,数组中的元素默认初始化)
  • 数组元素类型[] 数组名=new 数组元素类型[]{数组元素}; 注意:这种定义方法不能写数组元素个数
  • 数组元素类型[] 数组名={数组元素}  注意:这种定义方法虽然没用new,但是创建的数组也是对象

使用数组还需要注意:当访问数组不存在的下标,运行时会发生ArrayIndexOutOfBoundsException异常;当数组引用没有引用实体,还在用其操作实体,运行时会发生NullPointerException异常。不过这两种异常不会被编译器发现,它们属于运行时异常(Runtime Exception)。

定义一维数组、使用常规算法和Arrays类静态方法完成对一维数组的遍历排序等操作的示例代码如下:

<pre name="code" class="java">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);//[I@304e94a4   对象类型+@+十六进制哈希值System.out.println(arr_1.hashCode());//810456228  哈希值System.out.println(Integer.toHexString(arr_1.hashCode()));//304e94a4  十六进制哈希值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);//[I@7700b3c2 对象类型+@+十六进制哈希值System.out.println(Arrays.hashCode(arr_2));//33796  哈希值System.out.println(Arrays.toString(arr_2));//使用Arrays类的toString静态覆盖方法将数组转为字符串格式,[4,5,6]//第三种定义格式:int[] arr_3={7,8,9};System.out.println(arr_3);//[I@4f19c297  对象类型+@+十六进制哈希值System.out.println(Arrays.hashCode(arr_3));//36775  哈希值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);//43int 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]);//43int 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]);//43System.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));//2System.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);//falseSystem.out.println(a.equals(b));//falseSystem.out.println(Arrays.equals(a, b));//trueSystem.out.println(c==d);//falseSystem.out.println(c.equals(d));//falseSystem.out.println(Arrays.equals(c, d));//true}}


细心的人,比如我,有一些疑问:1.哈希值和内存地址是什么?为什么使用两种方式得到的哈希值不同?2.为什么数组使用==和equals会得到false,而使用Arrays的equals方法又能得到true?3.引用类型和对象是什么?和基本数据类型有何不同?这些疑问将在之后的几篇文章中详细解答

二、二维数组

说完了一维数组,二维数组就比较简单了,可以简单将其理解为表(Table)。与一维数组的不同主要就是定义格式和三个Arrays类针对多维数组操作的静态方法,直接看示例程序:

public class Test19 {public static void main(String[] args){//第一种定义格式int[][] arr_1=new int[2][3];//数组所有元素有默认值0System.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]);//nullSystem.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);//falseSystem.out.println(arr_4.equals(arr_5));//falseSystem.out.println(Arrays.deepEquals(arr_4, arr_5));//trueSystem.out.println(arr_6==arr_7);//falseSystem.out.println(arr_6.equals(arr_7));//falseSystem.out.println(Arrays.deepEquals(arr_6, arr_7));//true}}


0 0
原创粉丝点击