JavaSE第三十四讲:Arrays类解析及数组疑难剖析

public class Swap{
	public static void swap(int a, int b){
		int temp = a;
		a = b;
		b = temp;
	}

	public static void main(String[] args) {
		int x = 3;
		int y = 4;

		Swap.swap(x, y);
		System.out.println(x);
		System.out.println(y);

		System.out.println("--------------------------------");

		int temp = x;
		x = y;
		y = temp;
		System.out.println(x);
		System.out.println(y);

	}
}
编译执行结果:
D:\src>java Swap
3
4
--------------------------------------
4

3
【说明】:第一组数据输出结果不变,依然是3和4原因是因为x和y是原生数据类型,在数据传递过程中,赋完值后你是你,我是我。之间没有任何变化。所以不会因为调用这个函数而把值发生改变。第二组数据出现转换是因为这个转换的动作是在内部进行的,在内部处理完之后直接输出,没有值的传递过程。这一个要注意啊。


针对上一个程序,另外一种交互两个值的办法,如下所示:【这个方法很另类,不传统,但能体现小学数学的思维】

		int a = 3;
		int b = 4;

		a = a + b;
		b = a - b;
		a = a - b;

		System.out.println(a);
		System.out.println(b);

【说明】:通过这种不经过临时变量,同样实现了两个数字的转换。


请看以下例子:

public class Swap2{
	public static void swap(char[] ch, char c){
		ch[0] = 'B';
		c = 'D';
	}

	public static void main(String[] args) {
		char[] ch = {'A', 'C'};

		swap(ch, ch[1]);
		for(int i = 0; i < ch.length; i++){
			System.out.println(ch[i]);
		}
	}
}

编译执行结果:

D:\src>java Swap2
B
C

【说明】:首先要知道,1)数组变量本身就是一个引用,在执行swap()方法之前,内存如图34—1黑色线所示,ch引用指向数组首地址,ch赋给swap形式参数之后,内存发生如红色线所以,同样有swap()方法中的ch也指向了数组首地址,同是将数组首地址内容改为'B' ,而ch[1]传递过去本身就是传递char类型的原生数据类型,传完之后就不再变化,这与上一个程序类似

这个程序与之前程序中的方法传递原理类似。记住数据变量本省就是一个引用这个概念

图34-1


通过上面几个例子我们知道,如果通过方法实现对原生数据类型进行操纵,比如说两个值之间的交换。用传递原生数据值的到方法中进行交换得到结果是无效的,因为传递原生数据类型并不会改变内存中的值。那么通过什么办法可以再方法中实现对原生数据类型的操作呢?答案是数组,利用数组变量本省是引用可以操纵内存中的地址的特性将所操作的值放入数组中进行实现。


【程序例子】将a = 1, b = 2进行交换,必须通过方法进行实现,实现结果为a = 2, b = 1;将a,b的值用数组i来存储。

public class Swap3{
	public static void swap(int[] i){
		int temp = i[0];
		i[0] = i[1];
		i[1] = temp;
	}

	public static void main(String[] args){
		int[] i = {1, 2};
		swap(i);
		System.out.println(i[0]);
		System.out.println(i[1]);
	}
}

编译执行结果:

D:\src>java Swap3
2
1


以下例子是否可以编译通过,是否合法的?【很好的例子】

public class ArrayTest6{
	public static void main(String[] args) {
		I[] i = new I[2];
	}
}

interface I{

}

【说明】:这个例子是可以编译通过的,首先I[] i = new I[2];这条语句会在内存中生成一个长度为2的数组,数组里面每个元素都是I类型的,所以内存结构如下图34-2所示,这两个元素都是 数组的引用。也就是说这条语句并没有生成对象的意思,就只生成一个数组的对象之外,并没有生成一个接口I的实例(接口不能创建接口类型的实例滴),这点是关键,这就像是I j = null;语句,这是合法,它生成了I类型的引用j但是指向为空,但是它可以指向任何的子类,这是允许的

所以这仅仅是定义一个数组的声明:告诉编译器生成一个I类型的长度为2的数组,数据里面的元素指向任何的对象。

下面这个程序就可以让数组里面的元素指向实现这个接口I的子类的实例了


public class ArrayTest6{
	public static void main(String[] args) {
		I[] i = new I[2];

		i[0] = new C();
		i[1] = new C();
	}
}

interface I{

}

class C implements I{

}

【说明】:此时数组里面的元素是I类型的,同时指向了实现了I这个接口的类的实例。这其中隐含了多态的概念。这个程序需要对数据内容,整个内存运行情况都弄懂了才是真正的理解

图34-2


【说明】:上面那三行程序

		I[] i = new I[2];

		i[0] = new C();
		i[1] = new C();

也可以用下面一行来写,这种写法也是以后开发常用的写法

I[] b = new I[]{new C(), new C()};


【程序】:判断数组是否相同?1)数组长度相同,2)数组各个元素值相同

public class ArrayEqualsTest{
	public static boolean isEquals(int[] a, int[] b){
		
		//Compare Null or not between two arrays
		if(a == null || b == null){
			return false;
		}

		//Compare length between two arrays	
		if(a.length != b.length){
			return false;
		}

		for(int i = 0; i < a.length; i++){
			if(a[i] != b[i]){
				return false;
			}
		}

		return true;
	}

	public static void main(String[] args) {
		int[] a = {1, 2, 3};
		int[] b = {1, 2, 3};
		System.out.println(isEquals(a, b));
	}
}

编译执行结果:

D:\src>java ArrayEqualsTest
true



注意:java中JDK提供了一个类Arrays,里面的方法专门用来对数组的进行一些辅助功能的动作。

java.util里面的类专门为我们做一些辅助功能的动作

查看JDK API方法Arrays

java.util
    Class Arrays
  java.lang.Object 
  java.util.Arrays 

public class Arrays
extends Object
This class contains various methods for manipulating arrays (such as sorting and searching). This class also contains a static factory that allows arrays to be viewed as lists.

The methods in this class all throw aNullPointerException, if the specified array reference is null, except where noted.

查看类里面的方法,可以发现都是static方法,static方法我们是可以通过类名来直接调用的,通常在实际开发中,经常会把完成一些辅助功能的方法定义为static方法,一般有一些类,把这个类里面的方法全部定义为static,里面没有定义其他东西了,类似于abstract类。


通过API文档提供的equals方法,如下图34-4所示,对上一个程序进行判断。

图34-4


import java.util.Arrays;
public class ArrayEqualsTest{
	public static boolean isEquals(int[] a, int[] b){
		
		//Compare Null or not between two arrays
		if(a == null || b == null){
			return false;
		}

		//Compare length between two arrays	
		if(a.length != b.length){
			return false;
		}

		for(int i = 0; i < a.length; i++){
			if(a[i] != b[i]){
				return false;
			}
		}

		return true;
	}

	public static void main(String[] args) {
		int[] a = {1, 2, 3};
		int[] b = {1, 2, 3};
		System.out.println(isEquals(a, b));

		System.out.println(Arrays.equals(a,b));
	}
}
编译执行结果:

D:\src>java ArrayEqualsTest
true
true




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值