对重写equals与hashcode理解

/ 技术 / 无站内评论 / 282浏览

先看下百科对HashCode的解释:

1:Object类的hashCode.返回对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。 2:String类的hashCode.根据String类包含的字符串的内容,根据一种特殊算法返回哈希码,只要字符串所在的堆空间相同,返回的哈希码也相同。 3:Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer i1=new Integer(100),i1.hashCode的值就是100 。由此可见,2个一样大小的Integer对象,返回的哈希码也一样。

1.两个对象equals相等那么hashcode 是一定相等的。

2.两个对象equals不相等hashcode可能相等可以不相等。

因为hashCode说白了是地址值经过一系列的复杂运算得到的结果,而Object中的equals方法底层比较的就是地址值,所以equals()相等,hashCode必定相等,反equals()不等,在java底层进行哈希运算的时候有一定的几率出现相等的hashCode,所以hashCode()可等可不等。

通过对于这两个方法的使用: equals和hashcode,在set 集合框架中体现是最突出了。

这两个方法的调用原则是: 一、先去调用hashcode方法比较,如果相等的情况下再去调用equals方法比较,这时equals相等那边认为是同一个对象,则不同对象。二、先去调用hashcode方法不相等了,这样就不会去调用equals方法做比较的。所以,我们在写程序时一般会重写这两个方法。


public class Hello {

	public static void main(String[] args) {
		
		/**
		 * 重写equals时对象的相同与否是根据自身的需求进行判定
		 * 下面用户例子中,我们认为一个用户是否为同一个根据用户的name进行判定。
		 * 如果用户姓名一样则判定两个对象为同一个用户。
		 */
		User u1=new User(1,"a");
		User u2=new User(1,"a");
		
		/**
		 * 这两个方法的调用原则是: 一、先去调用hashcode方法比较,	(如果两个用户的name属性相同,则hashcode相同)
		 * 如果相等的情况下再去调用equals方法比较					
		 * 这时equals相等那边认为是同一个对象,则不同对象。
		 * 二、先去调用hashcode方法不相等了,这样就不会去调用equals方法做比较的。
		 * 所以,我们在写程序时一般会重写这两个方法。
		 */
		System.out.println(u1+":"+u1.hashCode());
		System.out.println(u2+":"+u2.hashCode());
		
		System.out.println(u1.equals(u2));
		


		运行结果:
			User@61:97
			User@61:97
			true


		
	}

}
运行

public class User {
	private int id;
	private String name;

	public int getId() {
		return id;
	}

	public User() {
		super();
	}

	public User(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof User) {
			User users = (User) obj;	
			/**
			 * 我们认为一个用户姓名相同就判定为同一个用户
			 */
			if (this.getId() == users.getId() && this.getName().equals(users.getName())) {
				return true;
			}
		}
		return false;
	}
	
	@Override
	public int hashCode() {
		/**
		 * 	在hashCode中返回他们name字段的HashCode值,
		 * 	如果两个参数的name相同则HashCode一定相同(两个对象equals相等那么hashcode 是一定相等的。)
		 * 	如果HashCode不同则判定两个对象不相同。
		 */
		return this.getName().hashCode();
	}

}

召唤蕾姆
琼ICP备18000156号

鄂公网安备 42011502000211号