【问题标题】:what is the difference between == operator and equals()? (with hashcode() ???)== 运算符和 equals() 有什么区别? (使用哈希码()???)
【发布时间】:2011-05-29 04:02:09
【问题描述】:

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

1.如果你重写equals(),你也必须重写hashcode()。

2。要查找 2 个对象是否是同一个对象,请使用 == 运算符

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

if(object1 == object2)

确实在做

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

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

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;
    }
}

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

所以我的问题是== operator 是否可以用来比较对象是否相同,覆盖 equals()hashCode() 比较方法的意义何在? == operator 不是已经做好了吗?

参考:

Overriding hashCode() - is this good enough?

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

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

【问题讨论】:

  • @All:谢谢大家的解释。这就是我喜欢stackoverflow的原因。很多聪明人可以描述和给出很好的例子,比只提供定义的官方文档要好得多:D

标签: java operators equals hashcode


【解决方案1】:

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

所以

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

 o1 == o2; //true

 o2 = new Object();

 o1 == o2 // false

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

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

o1 == o2 
o1.equals(o2) 

应该是真的。

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

【讨论】:

  • 那么什么时候会用到hashcode()?我们是否决定在 equals() 方法中使用哈希码进行比较?
  • 散列码被各种基于散列的集合使用,例如散列集。是否在 equals 中使用哈希码由您决定,但请注意,如果 2 个对象返回相同的哈希码,它们并不总是相等的。我不会。
【解决方案2】:

== 是身份。

.equals() 是平等的。

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

【讨论】:

    【解决方案3】:

    大部分都已经回答了,所以这里只是另一个启发性的例子:

    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
    

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

      • 这个周末要去书店 :D 那将是我的圣诞礼物!
      • @Fortyrunner 你能告诉我那本书的哪些部分解释了这些事情吗?
      • 本书第8项和第9项。
      【解决方案5】:

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

      .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() 是一种优化技巧(无论如何,在它的大多数用途中)。标准库中的大量代码假设如果o1.equals(o2)==trueo1.hashCode()==o2.hashCode(),如果o1.hashCode()!=o2.hashCode()o1.equals(o2)==false 以更快地工作。

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

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

      【讨论】:

        【解决方案6】:

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

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

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

        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;}  
        }        
        }
        

        【讨论】:

          猜你喜欢
          • 2011-10-09
          • 2010-10-02
          • 2022-12-14
          • 2023-03-04
          • 2011-08-31
          • 2019-04-17
          • 1970-01-01
          • 2022-06-10
          • 2016-03-20
          相关资源
          最近更新 更多