Java中的equals、hashCode、==

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

畅所欲言,欢迎来喷。


转载请标明出处,本文地址: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 anObject) {
       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、==)