美文网首页
Java中的equals、hashCode、==

Java中的equals、hashCode、==

作者: DB_BOY | 来源:发表于2019-08-20 11:34 被阅读0次

    本着针对面试,不负责任的态度,写下《面试总结》系列。本系列记录面试过程中各个知识点,而不是入门系列,如果有不懂的自行学习。

    畅所欲言,欢迎来喷。


    转载请标明出处,本文地址:https://www.jianshu.com/p/b7f28817bad1

    不负责任系列


    面试中经常会问到这类问题。如下:

    String s1="123";
    String s2="123";
    String s3=new String("123");
    System.out.println(s1==s2);
    System.out.println(s1==s3);
    System.out.println(s1.equals(s2));
    
    1. 两个类对象的hashCode相等,对象相等吗?equals相等,对象相等吗?

    以上两种算是一类问题。

    首先,要说1中==操作的问题,对String赋值,而非new出来的对象,这类值通常会存放在常量池中,不会在堆中创建对象,所以s1与s2指向的是同一个地址。s3是new出来的,那么会在堆中创建对象,在s3指向的是堆中的地址,所以s1==s3比较的是地址。

    其次,equals操作,由于String类中重写了equals方法,而Object类中的equals方法是直接做的==比较。

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

    String类中重写了equals()方法

    //String.java
    public boolean equals(Object var1) {
           if (this == anObject) {
                return true;
            }
            if (anObject instanceof String) {
                String anotherString = (String)anObject;
                int n = value.length;
                if (n == anotherString.value.length) {
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {
                        if (v1[i] != v2[i])
                            return false;
                        i++;
                    }
                    return true;
                }
            }
            return false;
    

    从源码中可以看到,先从==判断,这个判断的是引用,如果不想等,接下来是循环字符串,判断的字符串里面的内容,如果每个字符都相等,两个String对象才相等。

    从String类引申出来,我们能不能直接说==判断的是对象的地址,equals()判断的是对象的内容呢?
    答案是不可以,那么为什么呢?
    ==判断的是两个对象的地址,这个毋庸置疑,但是equals()这个是不确定的。

    我们知道equals()方法是Object中的,也就是说,所有的对象都可以去覆盖重写该方法。没有重写equals()的时候,默认的equals()方法,等价于==方法。如果像String中那样,每个类都有自己的逻辑,自定义个类,重写equals()方法,恒返回true,那么怎么能够判断出来对象是相等呢?或者如学生类,重写equals()的时候,判断学生的姓名,年龄,性别,学号相等,那么返回true,这个也是符合自己的逻辑,但不能说明两个类对象是相等的。

    hashCode跟equals又是什么关系

    默认的Object中的hashCode()是用的native层,得到一个hash值。

      public native int hashCode();
    
    1. 类没有重写hashCode方法,那么类对象equals比较的时候,跟hashCode没有任何关系。

    2. 重写了hashCode()方法。
      a. equals相等的两个对象,hashCode()得到值一定相等
      b. hashCode值相等的两个对象,equals不一定相等。

    b)中的情况,可以从HashMap等使用hash值的集合中得到结果。当hash值相等的时候,说明发生了hash冲突。

    重要的事情
    在决定重写hashCode()方法的时候,一定要做到规范,有含义,不然如果在对象添加到HashMap等集合中发生冲突的概率会大大提高。

    相关文章

      网友评论

          本文标题:Java中的equals、hashCode、==

          本文链接:https://www.haomeiwen.com/subject/plvusctx.html