equals函数,hashCode(),toString()的作用和实现方法

今天学习到equals函数的作用,这里就写下我的心得吧。

首先先了解一下双等号“==”的作用

双等号“==”用来比较引用数据类型的时候,就判断双等号“==”两边的引用是否指向堆内存的同一块地址,

或者说是否指向堆内存里的同一个对象。

User.java

class User {
	String name;
	int age;
}

Test.java

class Test{
	public static void main(String[] args){
		User u1 = new User();
		User u2 = new User();
		User u3 = u1;
		
		boolean b1 = u1 == u2;
		boolean b2 = u1 == u3;
		System.out.println(b1);
		System.out.println(b2);
	}
}
为什么要先举双等号的例子呢,因为双等号的作用和这次学的equals函数的作用很容易混淆。

先说一下这里的结果,结果是第一个false第二个true


这一次要学习的是equals函数,它用来比较两个对象的内容是否相等

通常情况下,对象的内容相等需要符合两个条件:

1.对象的类型相同(可以使用instanceof操作符进行比较);

2.两个对象的成员变量的值完全相同;

这里需要注意的是,我们在使用equals函数的时候,不能直接调用obj的equals函数,而是应该自己复写一个,因为obj的equals函数实际上也是用的双等号比较,

所以我们需要复写equals函数

User.java

class User {
	String name;
	int age;

	public boolean equals(Object obj){
		if(this == obj){
			return true;
		}

		boolean b = obj instanceof User;
		if(b){
			User u = (User)obj;
			if(this.age == u.age && this.name.equals(u.name)){
				return true;
			}
			else{
				return false;
			}
		}
		else{
			return false;
		}
	}
}

比较基本数据类型的时候直接用双等号比,而比较引用数据类型的时候就用equals比,因为引用数据类型有定义相应的equals函数。


Test.java

class Test{
	public static void main(String[] args){
		User u1 = new User();
		User u2 = new User();
		User u3 = new User();

		u1.name = "zhangsan";
		u1.age = 12;

		u2.name = "lisi";
		u2.age = 12;

		u3.name = "zhangsan";
		u3.age = 12;

		System.out.println(u1.equals(u2));
		System.out.println(u1.equals(u3));
	}
}

这样就把equals复写成功,并测试成功了。

明显可以看出,u1和u2是不同的,而u1跟u3是符合要求的。所以应返回

false 

true


hashCode()和toString()都存在于Object这个类中。所有类都从Object中继承了这两个方法

Hash算法,是指将任意长度的数据(二进制)通过Hash算法,能生成唯一的散列值,

User.java

class User{
	String name;
	int age;

	public User(){

	}

	public User(String name,int age){
		this.name = name;
		this.age = age;
	}
	public boolean equals(Object obj){
		if(this == obj){
			return true;
		}

		if(obj instanceof User){
			User u = (User)obj;
			if(this.age == u.age && this.name.equals(u.name)){
				return true;
			}
			else{
				return false;
			}
		}
		else{
			return false;
		}
	}
}

Test.java

import java.util.*;

class Test{
	public static void main(String[] args){
		User u = new User("zhangsan",12);

		HashMap<User,String> map = new HashMap<User,String>();
		map.put(u,"abc");

		String s = map.get(new User("zhangsan",12));
		System.out.println(s);
	}
}

照理说,键为u,保存了键值为abc,而我们用get提取的时候应该也是abc才对,但结果却是null、

由于我们没有复写hashCode(),所以它们返回的hash码是不一样的。

修改User.java,复写hashCode();

class User{
	String name;
	int age;

	public User(){

	}

	public User(String name,int age){
		this.name = name;
		this.age = age;
	}
	public boolean equals(Object obj){
		if(this == obj){
			return true;
		}

		if(obj instanceof User){
			User u = (User)obj;
			if(this.age == u.age && this.name.equals(u.name)){
				return true;
			}
			else{
				return false;
			}
		}
		else{
			return false;
		}
	}

	public int hashCode(){
		return 12;
	}
}

Test.java不变,编译运行,结果就是abc.

这里复写的hashCode是简单的。

下面有另外一种复写

User.java

class User{
	String name;
	int age;

	public User(){

	}

	public User(String name,int age){
		this.name = name;
		this.age = age;
	}
	public boolean equals(Object obj){
		if(this == obj){
			return true;
		}

		if(obj instanceof User){
			User u = (User)obj;
			if(this.age == u.age && this.name.equals(u.name)){
				return true;
			}
			else{
				return false;
			}
		}
		else{
			return false;
		}
	}

	public int hashCode(){
		int result = 11;

		result = 31 * result + age;
		result = 31 * result + name.hashCode();
		return result;
	}
}

下面介绍toString()用法,User.java不变,Test.java改为

import java.util.*;

class Test{
	public static void main(String[] args){
		User u = new User("zhangsan",12);

		System.out.println(u);
	}
}

这里的System.out.println(u);是先运行u.toString(),然后再打印出来的。


这时编译运行的结果是

User@aa9c5b33

而这个toString()也是可以复写的。

同样方法,在User.java下面加

public String toString(){
		String result = "age:" + age + "," + "name:" + name;
		return result;
	}

这样就可以了。运行结果是

age:12,name:zhangsan


这是我的学习心得,如果写得不对或者不足之处,请原谅,并指出错误,谢谢。

转载于:https://my.oschina.net/u/860952/blog/549223

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值