java == 运算符和 equals() 有什么区别?(使用哈希码()???)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4505357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:39:45  来源:igfitidea点击:

what is the difference between == operator and equals()? (with hashcode() ???)

javaoperatorsequalshashcode

提问by Meow

I was learning hashcode in more depth and figured that:

我正在更深入地学习哈希码并认为:

1. If you override equals(), you must override hashcode() too.

1. 如果你覆盖了equals(),你也必须覆盖hashcode()。

2. To find if 2 objects are same object, use == operator

2. 判断2个对象是否为同一个对象,使用==操作符

Given those 2 factors, in Java I was assuming that when == operatoris used to compare if 2 instances are same or not,

鉴于这两个因素,在 Java 中,我假设 when== operator用于比较2 个实例是否相同,

if(object1 == object2)

is actually doing

实际上在做

if(object1.hashcode() == object2.hashcode())

But it appears I was wrong by running the test below.

但是通过运行下面的测试似乎我错了。

public class Main {

    public static void main(String[] args){
        Obj1 one = new Obj1();
        Obj1 two = new Obj1();
        //is this calling hashCode() in backend???
        if(one == two) {
            System.out.println("same");
        }
        else {
            System.out.println("nope");
        }
        //this is of course return true
        if(one == one) {
            System.out.println("one and one is same");
        }
    }
}

class Obj1 {
    @Override
    public int hashCode() {
        System.out.println("hashCode() is called");
        return 111;
    }
    @Override
    public boolean equals(Object another) {
        System.out.println("equals() is called");
        return false;
    }
}

According to the test which uses == operatorand see if equals()is called and it wasn't.

根据使用的测试,== operator看看是否equals()被调用,它没有被调用。

So my question is if == operatorcan used to compare if the object is same or not, what is the point of overriding equals()and hashCode()method for comparison? Isn't == operatordo the job already?

所以我的问题是如果== operator可以用来比较对象是否相同,覆盖 equals()hashCode()方法进行比较有什么意义?不是== operator已经完成任务了吗?

reference:

参考:

Overriding hashCode() - is this good enough?

覆盖 hashCode() - 这是否足够好?

http://mindprod.com/jgloss/hashcode.html

http://mindprod.com/jgloss/hashcode.html

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#equals(java.lang.Object)

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#equals(java.lang.Object)

回答by hvgotcodes

the == operator determines if 2 references point to the same object.

== 运算符确定 2 个引用是否指向同一个对象。

So

所以

 Object o1 = new Object();
 Object o2 = o1;

 o1 == o2; //true

 o2 = new Object();

 o1 == o2 // false

the Object.equals() method is "how do I determine if 2 references to objects, that are not the same object, are equal?"

Object.equals() 方法是“如何确定对对象的 2 个引用(不是同一个对象)是否相等?”

If two references point to the same object, both

如果两个引用指向同一个对象,

o1 == o2 
o1.equals(o2) 

should be true.

应该是真的。

But if o1 and o2 are not the same object, they still mightbe equal logically. For any given class, equals depends on the semantics behind the object. For example, consider a class where field1 and field2 are set by the user, but field3 is computed and has a random element to its computation. It might make sense to define equals in this case to only depend on field1 and field2, and not field3. Thats why equals is necessary.

但是如果 o1 和 o2 不是同一个对象,它们在逻辑上仍然可能相等。对于任何给定的类,equals 取决于对象背后的语义。例如,考虑一个类,其中 field1 和 field2 由用户设置,但 field3 是计算的,并且有一个随机元素进行计算。在这种情况下,将 equals 定义为仅依赖于 field1 和 field2 而不是 field3 可能是有意义的。这就是为什么 equals 是必要的。

回答by Laurence Gonsalves

==is identity.

==是身份。

.equals()is equality.

.equals()是平等。

.equals()defaults to just using ==(just like hashCode()defaults to System.identityHashCode()but you can override them if there's a more meaningful way to check for equality. Typically this is a sort of "structural" equality. ie: are all of the pieces of this.equal()to all of the pieces of that?

.equals()默认为仅使用==(就像hashCode()默认为,System.identityHashCode()但如果有更有意义的方法来检查相等性,您可以覆盖它们。通常这是一种“结构”相等性。即:是所有部分的this.equal()所有部分that?

回答by Fortyrunner

If you don't already have a copy; buy a copy of Effective Java by Joshua Bloch.

如果您还没有副本;购买 Joshua Bloch 的 Effective Java 的副本。

This is the de facto reference for Java developers and has a lot of information on this (and many other) subject.

这是 Java 开发人员的事实上的参考资料,其中包含有关此(以及许多其他)主题的大量信息。

回答by Bill Michell

==(used on objects rather than on primitive values) tests whether 2 objects are actually the same object; it compares whether the pointers are actually pointing to the same memory location.

==(用于对象而不是原始值)测试 2 个对象是否实际上是同一个对象;它比较指针是否实际指向相同的内存位置。

.equals()is defined by the object itself.

.equals()由对象本身定义。

String s1 = new String("Hello");
String s2 = new String("Hello");

boolean b1 = ( s1 == s2 ) ; // false: s1 and s2 point to different objects
boolean b2 = ( s1.equals(s2) ) ; // true: s1 and s2 both represent the same
                                 //       piece of text - "Hello"

.hashCode()is an optimisation trick (in most of its uses, anyway). A lotof code in the standard libraries makes the assumption that if o1.equals(o2)==truethen o1.hashCode()==o2.hashCode()and that if o1.hashCode()!=o2.hashCode()then o1.equals(o2)==falsein order to work faster.

.hashCode()是一个优化技巧(无论如何,在它的大多数用途中)。一个很大的标准库中的代码,使假设,如果o1.equals(o2)==trueo1.hashCode()==o2.hashCode()和,如果o1.hashCode()!=o2.hashCode()o1.equals(o2)==false为了工作得更快。

The most obvious example of such an optimisation is the HashMapclass. This makes retrieving objects using a key reallyfast, but breaks badly if hashCode and equals don't work properly for the key elements. In fact, this is one of the reasons that the String class is immutable: if you were able to modify a String (and so change its hashCode) while that String was the key in a HashMap, then you would never be able to find it, since you would end up looking for it in the wrong place!

这种优化最明显的例子是HashMap类。这使得使用键检索对象的速度非常快,但如果 hashCode 和 equals 不能对关键元素正常工作,则会严重中断。事实上,这是 String 类不可变的原因之一:如果您能够修改 String(并因此更改其 hashCode)而该 String 是 HashMap 中的键,那么您将永远无法找到它,因为你最终会在错误的地方寻找它!

Other answers recommend Effective Javaby Joshua Bloch. If you are asking such questions, then now is the perfect time in your career to buy the book and read it cover to cover. It'll also be worth re-reading it in a year or two's time, when you'll have forgotten some of it and more of it will make sense...

其他答案推荐Joshua Bloch 的Effective Java。如果您提出此类问题,那么现在是您职业生涯中购买本书并从头到尾阅读的最佳时机。在一两年后重新阅读它也是值得的,当你忘记了其中的一些并且更多的时候会有意义......

回答by BalusC

Most is already answered, so here's just another enlightening example:

大多数已经回答了,所以这里只是另一个有启发性的例子:

String s1 = "foo";
String s2 = "foo";
System.out.println(s1 == s2); // true, because same reference (string pool)

String s3 = new String("foo");
String s4 = new String("foo");
System.out.println(s3 == s4); // false, because different reference
System.out.println(s3.equals(s4)); // true, because same value

回答by voore vamshi

==operator --> checks weather 2 references point to the same object or not. If same it return true otherwise false.

==运算符 --> 检查天气 2 引用是否指向同一个对象。如果相同,则返回 true 否则返回 false。

equals( )--> checks both reference and state object. Hear state means object data. In this any one is true it returns true. Otherwise false. But we have to override equals( )in our user defined object and write the appropriate code.

equals( )--> 检查引用和状态对象。听到状态意味着对象数据。在这任何一个是真的它返回真。否则为假。但是我们必须覆盖equals( )我们用户定义的对象并编写适当的代码。

Hashcode( )-->hashCode of an Object just represents a random number which can be used by JVM while saving/adding Objects into Hashsets, Hashtables or Hashmap.

Hashcode( )--> 一个对象的hashCode 只是代表一个随机数,JVM 在将对象保存/添加到Hashsets、Hashtables 或Hashmap 中时可以使用它。

Example of hashcode()

示例 hashcode()

class TestHasChode
{
int i;
TestHasChode(int i)
{
this.i = i;
}

public static void main(String arg[])
{  
    //before overriding hashcode()  
TestHasChode t1 = new TestHasChode(100);   
TestHasChode t2 = new TestHasChode(110);

System.out.println(t1); //TestHasChode@45e41830  
System.out.println(t2); //TestHasChode@1f01b29  

TestHasChode t3 = new TestHasChode(100);  
TestHasChode t4 = new TestHasChode(100);  
System.out.println(t3); //TestHasChode@3a8721bd   
System.out.println(t4); //TestHasChode@7db81d4f

/*hashCode() of Object class implemented to return hashCode based on address of an object, but based
on our requirement we can override hashCode() to generate our own numbers as hashCodes*/

//after overriding hashcode()  
System.out.println(t3); //TestHasChode@64  
System.out.println(t4); //TestHasChode@64  
}  
public int hashCode(){
return i;
}  
}  
-->Example of equals()method      
class Student
{
String name;   
int rollno;   
Student(String name,int rollno)
{   
this.name = name;    
this.rollno = rollno;   
}   
public static void main(String arg[])
{       
    //before overrideng equals method    
Student s1 = new Student ("raju", 101);     
Student s2 = new Student ("giri", 102);     
Student s3 = new Student ("giri", 102);     
System.out.println(s1.equals(s2));//false    
System.out.println(s2.equals(s3));//false    
    //after overriding equals method    
System.out.println(s1.equals(s2));//false    
System.out.println(s2.equals(s3));//true-->hear overriding equals() checks state.so it is true.  
    //in string variables comparisition   
    String s4="hello";    
    String s5=new String("hello");    
    String s6=new String("hello");   
System.out.println(s4.equals(s5));//true--> because String class containg overridden equals method   
System.out.println(s5.equals(s6));//true-->even though differnet object reference but String class containg overridden equals method   

}     
public boolean equals(Object obj){   
String name1 = this.name;   
int rollno1 = this.rollno;   
Student s2 = (Student)obj;     
String name2 = s2.name;     
int rollno2 = s2.rollno;    
if(name1.equals(name2) && rollno1 == rollno2){   
return true;}   
else{     
return false;}  
}        
}