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

一、一维数组和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);//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
	}
}


 
细心的人,比如我,有一些疑问: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];//数组所有元素有默认值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
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值