Java:equals和hashCode的理解

我们一般使用equals都是为了比较对象的内容,而Object里面的equals方法却是比较对象的引用,如下:

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

所以当我们想要比较的是对象的内容时,需要重写equals方法,假设User类中有String name , int age 两个字段,用eclipse自动生成的equals方法写法如下:

public boolean equals(Object obj) {
	if (this == obj)
		return true; // 两者引用相等则是同一个对象故内容相等
	if (obj == null)
		return false;
	if (getClass() != obj.getClass())  // 两者的类不相等,则内容不可能相等
		return false;
	User other = (User) obj;  // 将其向下转型
	if (age != other.age)  // 下面就是开始比较内容
		return false;
	if (name == null) {
		if (other.name != null)
			return false;
	} else if (!name.equals(other.name))
		return false;
	return true;
}

一个测试用例

public class Test {
	public static void main(String[] args) {
		User user1 = new User();
		User user2 = new User();
		System.out.println(user1.equals(user2));
 	}
}

打印true。如果把User类重写的equals方法去掉,此时user1.equals()调用的是Object类的equals方法,比较的是引用而不是内容,user1和user2的引用明显不同,故打印false。常用的equals方法比较的是对象的内容,即对象要属于同一个类且字段属性相等才相等。

HashCode主要用于类集框架。假设我们对一个类不重写hashCode方法,对象调用hashCode方法时则调用的是Object类的hashCode方法:

public native int hashCode();

生成的散列值都是不相同的,而如果我们重写了hashCode方法,对于内容相同的对象则可以生成相同的散列值。

至于hashCode方法写法,我们一般也不需要记住,直接用工具生成就好了。

测试用例:

public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		HashSet<User> set = new HashSet<>();
		User user1 = new User("leelit", 21);
		User user2 = new User("leelit", 21);
		User user3 = new User();

		System.out.println(user1.hashCode());
		System.out.println(user2.hashCode());
		System.out.println(user3.hashCode());

		set.add(user1); // 添加user1和user2
		set.add(user2);
		System.out.println(set.size());

		HashMap<User, String> map = new HashMap<>();
		map.put(new User("lina", 21), "value");
		System.out.println(map.get(new User("lina", 21)));
	}
}

打印结果:

-1106625705
-1106625705
961
1
value

把User类重写的hashCode方法去掉后打印:

31168322
17225372
5433634
2
null

没有重写hashCode方法时:两个对象即使内容相等,也生成不同的散列值,所以都可以add进set里面去,我们知道HashSet是不可以有重复的元素的,所以这就是为什么必须要重写hashCode的原因;同理对于HashMap虽然put和get的是同样的key,但由于散列值不同,而被视作了不同的key,所以无法取出来。

重写hashCode方法后,两个相等的对象会生成相同的散列值。

时间: 2024-10-13 06:22:11

Java:equals和hashCode的理解的相关文章

equals和HashCode深入理解以及Hash算法原理

equals()和HashCode()深入理解以及Hash算法原理 1.深入理解equals(): 在我的一篇博客"=="和.equals()的区别中向读者提出提醒: Object类中的equals方法和"=="是一样的,没有区别,即俩个对象的比较是比较他们的栈内存中存储的内存地址.而String类,Integer类等等一些类,是重写了equals方法,才使得equals和"==不同",他们比较的是值是不是相等.所以,当自己创建类时,自动继承了O

java :equals()和hashcode()方法的结合使用

哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现. 为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方法. 一.hashCode方法的作用 对于包含容器类型的程序设计语言来说,基本上都会涉及到h

java equals()和hashCode()重写总结

在实际开发中有时候会遇到需要比较同一个类的不同实例对象的场景,一般情况下继承自Object父类的equals()和hashCode()可以满足需求,但却不能满足所有的场景,比如只需要使用少数几个对象属性来判断比较是否是同一个对象,这时我们就需要自定义的equals()和hashCode()实现来进行重写覆盖Object中的方法. 1. equals()方法重写注意事项 a. 自反性:对于任意的引用值x,x.equals(x)一定为true. b. 对称性:对于任意的引用值x 和 y,当x.equ

Java == ,equals 和 hashcode 的区别和联系

1. ==  java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: public class ComAddr{ public static void main(String[] args) throws Exception { String s1 = "nihao"; String s2 = "nihao"; String s3 = new String("nihao"); System.out.println(s1 ==

JAVA中用堆和栈的概念来理解equals() &quot;==&quot;和hashcode()

在学习java基本数据类型和复杂数据类型的时候,特别是equals()"=="和hashcode()部分时,不是很懂,也停留了很长时间,最后终于有点眉目了. 要理解equals()"=="和hashcode(),最好先了解Java内存中堆和栈的知识: 下面一段是参考自http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html 大家也可点进去查看更详细的解释. Java 中的堆和栈  Java把内存划分成两种

理解Java中的hashCode和equals 方法

在Java里面所有的类都直接或者间接的继承了java.lang.Object类,Object类里面提供了11个方法,如下: Java代码   ```` 1,clone() 2,equals(Object obj) 3,finalize() 4,getClass() 5,hashCode() 6,notify() 7,notifyAll() 8,toString() 9,wait() 10,wait(long timeout) 11,wait(long timeout, int nanos) ``

Java 中的 ==, equals 与 hashCode 的区别与联系

一.概述 1.概念 == : 该操作符生成的是一个boolean结果,它计算的是操作数的值之间的关系 equals : Object 的 实例方法,比较两个对象的content是否相同 hashCode : Object 的 native方法 , 获取对象的哈希值,用于确定该对象在哈希表中的索引位置,它实际上是一个int型整数 二.关系操作符 == 1.操作数的值 基本数据类型变量 在Java中有八种基本数据类型: 浮点型:float(4 byte), double(8 byte) 整型:byt

Java 重写 equals 与 hashCode 的注意事项

为什么重写 equals 的时候必须重写 hashCode 大家可能从很多教程中了解到: SUN官方的文档中规定"如果重定义equals方法,就必须重定义hashCode方法,以便用户可以将对象插入到散列(哈希)表中" 那么 SUN 公司是出于什么考虑做了这个规定呢? 在集合框架中的HashSet,HashTable和HashMap都使用哈希表的形式存储数据,而hashCode计算出来的哈希码便是它们的身份证.哈希码的存在便可以: 快速定位对象,提高哈希表集合的性能. 只有当哈希表中对

【转】Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例

原文地址:http://www.cnblogs.com/luankun0214/p/4421770.html 感谢网友的分享,记录下来只为学习. 1.重写equals方法实例   部分代码参考http://blog.csdn.net/wangloveall/article/details/7899948 重写equals方法的目的是判断两个对象的内容(内容可以有很多,比如同时比较姓名和年龄,同时相同的才是用一个对象)是否相同 如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址