`
tottichen
  • 浏览: 13461 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

Java中== equals hashcode浅析

阅读更多
1. '=='是用来比较两个变量(基本类型和对象类型)的值是否相等的, 如果两个变量是基本类型的,那很容易,直接比较值就可以了。如果两个变量是对象类型的,那么它还是比较值,只是它比较的是这两个对象在栈中的引用(即地址)。
对象是放在堆中的,栈中存放的是对象的引用(地址)。由此可见'=='是对栈中的值进行比较的。如果要比较堆中对象的内容是否相同,那么就要重写equals方法了。
2. Object类中的equals方法就是用'=='来比较的,所以如果没有重写equals方法,equals和==是等价的。
通常我们会重写equals方法,让equals比较两个对象的内容,而不是比较对象的引用(地址)因为往往我们觉得比较对象的内容是否相同比比较对象的引用(地址)更有意义。
3. Object类中的hashCode是返回对象在内存中地址转换成的一个int值(可以就当做地址看)。所以如果没有重写hashCode方法,任何对象的hashCode都是不相等的。通常在集合类的时候需要重写hashCode方法和equals方法,因为如果需要给集合类(比如:HashSet)添加对象,那么在添加之前需要查看给集合里是否已经有了该对象,比较好的方式就是用hashCode。
4. 注意的是String、Integer、Boolean、Double等这些类都重写了equals和hashCode方法,这两个方法是根据对象的内容来比较和计算hashCode的。(详细可以查看jdk下的String.java源代码),所以只要对象的基本类型值相同,那么hashcode就一定相同。
5. equals()相等的两个对象,hashcode()一般是相等的,最好在重写equals()方法时,重写hashcode()方法; equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。 反过来:hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。在object类中,hashcode()方法是本地方法,返回的是对象的引用(地址值),而object类中的equals()方法比较的也是两个对象的引用(地址值),如果equals()相等,说明两个对象地址值也相等,当然hashcode()也就相等了。
以下是测试代码。
 public class Equals_HashCode {
    public static void main(String[] args) {        
         String a = new String("str");
         String b = new String("str");
         System.out.println(a==b);
         System.out.println(a.equals(b));
         System.out.println(a.hashCode());
         System.out.println(b.hashCode());
         // 输出 false true 114225 114225
         class A{
             String str;
             int i;
             public A(String str, int i) {
                 super();
                 this.str = str;
                 this.i = i;
             }
         }
         A aA = new A("str",1);
         A bA = new A("str",1);
         System.out.println(aA==bA);
         System.out.println(aA.equals(bA));
         System.out.println(aA.hashCode());
         System.out.println(bA.hashCode());
         // 输出 false false 6413875 21174459
         class B{
             String str;
             public B(String str){
                 this.str = str;
             }
         }
         B aB = new B("str");
         B bB = new B("str");
         System.out.println(aB==bB);
         System.out.println(aB.equals(bB));
         System.out.println(aB.hashCode());
         System.out.println(bB.hashCode());
         // 输出 false false 827574 17510567
         class C{
             int i;
             public C(int i){
                 this.i = i;
             }
         }
         C aC = new C(1);
         C bC = new C(1);
         System.out.println(aC==bC);
         System.out.println(aC.equals(bC));
         System.out.println(aC.hashCode());
         System.out.println(bC.hashCode());
         //输出 false false 27744459  28737396
    }
 
}
 
分享到:
评论
3 楼 五月天 2010-06-01  
引用

重写equal方法 一定要重写hashcode方法

也不一定吧?我觉得也只是在处理如HashMap,HashSet等通过哈希储存结构中会使用到hashCode。
当然,在重写equals方法时同时重写hashCode是个好的规范!
我刚才那代码只是想证明:equals方法判断对象相等时,hashCode不一定相等。
2 楼 akiraray 2010-06-01  
五月天 写道
引用

equals()相等的两个对象,hashcode()一定相等; equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。

是这样吗?我做了个测试
class Product {
	private int id;
	private String name;
	
	public Product(int id, String name) {
		this.id = id;
		this.name = name;
	}
	
	@Override 
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Product)) {
			return false;
		}
		Product other = (Product)obj;
		if (other.id != this.id) {
			return false;
		}
		return true;
	}
}


public class EqualsTest {
	public static void main(String[] args) {
		Product a = new Product(1, "zcl");
		Product b = new Product(1, "chunlei");

		System.out.println("equals: " + a.equals(b)); 
		System.out.println("a.hashCode:" + a.hashCode()); 
		System.out.println("b.hashCode:" + b.hashCode());
	}
}
/** (output)

D:\My Documents\javacode>javac EqualsTest.java

D:\My Documents\javacode>java EqualsTest
equals: true
a.hashCode:12677476
b.hashCode:33263331

*/

是我理解错了还是楼主讲得有问题?

重写equal方法 一定要重写hashcode方法
1 楼 五月天 2010-06-01  
引用

equals()相等的两个对象,hashcode()一定相等; equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。

是这样吗?我做了个测试
class Product {
	private int id;
	private String name;
	
	public Product(int id, String name) {
		this.id = id;
		this.name = name;
	}
	
	@Override 
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Product)) {
			return false;
		}
		Product other = (Product)obj;
		if (other.id != this.id) {
			return false;
		}
		return true;
	}
}


public class EqualsTest {
	public static void main(String[] args) {
		Product a = new Product(1, "zcl");
		Product b = new Product(1, "chunlei");

		System.out.println("equals: " + a.equals(b)); 
		System.out.println("a.hashCode:" + a.hashCode()); 
		System.out.println("b.hashCode:" + b.hashCode());
	}
}
/** (output)

D:\My Documents\javacode>javac EqualsTest.java

D:\My Documents\javacode>java EqualsTest
equals: true
a.hashCode:12677476
b.hashCode:33263331

*/

是我理解错了还是楼主讲得有问题?

相关推荐

    Java中的==和equals区别

    ### Java中的`==`与`equals`方法的区别详解 在Java编程中,比较对象的相等性是一个常见的需求,但很多初学者对于`==`运算符与`equals`方法的区别容易混淆。本文将深入探讨两者之间的差异,以及它们在不同场景下的...

    java中==和equals的区别

    前言 对于开发的程序员小伙伴,...equals:在Object中模式采用==比较,通常会重写 String对象重写了 equals,比较的是变量值 从上面我们笼统的来说明了一下两者的不同,那么接下来我们看看具体的区分 对象类型的比较

    ==和equals的区别

    Java 中的 == 和 equals 方法的区别 在 Java 中,比较值大小有两种方法:== 和 equals,这两个方法的使用场景和比较规则不同,下面我们将详细探讨它们的区别。 基本数据类型和引用数据类型 在 Java 中,有两种...

    ==与equals的比较

    "Java中的==和equals方法比较" 在Java中,`==`和`equals`是两种不同的比较方法,前者比较引用地址,而后者比较对象的实际内容。 首先,让我们来看看`==`运算符的用法。`==`运算符可以用来比较基本数据类型和引用...

    java中equals和==的区别

    Java 中 equals 和 == 的区别 Java 中的 equals 和 == 是两个不同的概念,很多开发者容易混淆它们。理解这两个概念的区别是非常重要的,因为它们对编程的正确性和性能都有很大的影响。 首先,我们需要了解 Java ...

    Java中equals,hashcode和==的区别

    "Java中equals、hashcode和==的区别" Java 中 equals、hashcode 和==的区别是 Java 编程语言中一个经常遇到的问题。这三个概念都是用来比较对象的,但是它们之间存在着本质的区别。 首先,==号是Java中的一个...

    Java中==与equals的区别小结

    在Java编程语言中,了解`==`和`equals()`的区别是非常重要的,这涉及到对基本类型和对象的正确比较。下面我们将详细探讨这两个操作符的工作原理及其在不同情况下的使用。 首先,`==`操作符主要用于比较基本类型的...

    java中的==和equals()方法1

    在Java编程语言中,了解如何正确使用`==`和`equals()`方法是非常关键的,因为它们在比较对象和基本类型时有不同的行为。下面将详细解释这两个方法的工作原理、使用场景以及一些常见误区。 首先,`==`运算符主要用于...

    Java重写equals同时需要重写hashCode的代码说明

    Java重写equals同时需要重写hashCode的代码说明,以及如何重写hashCode方法,此代码演示按照effective java书籍说明的重写思路。代码中演示了使用集合存储对象,并且对象作为key,需重写equals和hashCode.

    浅谈java 中equals和==的区别

    以下是关于 `equals()` 和 `==` 在Java中的详细解释。 首先,`==` 是Java中的一个二元运算符,用于比较两个变量的值。对于基本数据类型(如 int、double、char),`==` 直接比较它们的值是否相等。而对于引用类型...

    ==运算符和Equals()方法区别

    在C#语言中,`==`运算符和`Equals()`方法都是用来比较两个对象是否相等,但是它们之间存在着很大的区别。 对于值类型来说,`==`运算符和`Equals()`方法的行为是一致的,都会比较两个对象的值是否相等。例如,在上面...

    java基础之 “==”与“equals”区别详解

    在java中,“==”操作符用于比较两个对象是否相等。对于基本类型来说,“==”比较的是值是否相同;对于引用类型来说,“==”比较的是引用是否相同。 2. equals()方法的作用: equals()方法用于比较两个对象的值是否...

    ==和equals方法究竟有什么区别

    在Java编程语言中,`==`和`equals()`方法是用来比较对象之间关系的两种常见方式,但它们在使用上有着显著的区别。 首先,`==`运算符主要用于比较基本类型(如int、char、byte等)的值是否相等,或者比较引用类型...

    == and equals() 的比较 绝对值得看

    首先,我们要知道在Java中,值类型(如int、char)是存储在内存的栈中,而引用类型(如类实例)的变量实际上存储的是对象在堆中的地址。栈存储变量的直接值,而堆存储对象的实际内容。 `==`运算符用于比较两个变量...

    浅谈java中==以及equals方法的用法

    Java 中的 == 和 equals 方法的用法 Java 中的 == 和 equals 方法是两个常用的比较操作符,然而,它们的用法和作用却大不相同。本文将详细介绍 Java 中 == 和 equals 方法的用法、区别和应用场景。 一、== 操作符...

    简单介绍java中的“==”和equals

    简单介绍java中的“==”和equals

    java中hashcode()和equals()和==的详解

    有许多人学了很长时间的Java,但一直不明白hashCode...首先,想要明白hashCode的作用,你必须要先知道Java中的集合。总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set。你知道它们的区别吗?

    String中==与equals区别验证

    Java中,对象的创建有两种方式:通过字面量(如 `String a = "abc";`)和通过 `new` 关键字(如 `String c = new String("abc");`)。前者通常利用字符串池来提高效率和减少内存消耗,后者则总是在堆上创建新的对象...

    Java中==运算符与equals方法的区别及intern方法详解

    "Java中==运算符与equals方法的区别及intern方法详解" Java中==运算符与equals方法的区别是Java程序设计语言中的一個非常重要的概念,它們兩者都是用來比较字符串是否相等,但是它们的比较方式完全不同。 ==运算符...

    【Java面试题】equals与==的区别

    【Java面试题】equals与==的区别

Global site tag (gtag.js) - Google Analytics