关于java ==,equal() 以及 hashcode()

1.首先,'=='  大家都很熟悉就是比较地址,话不多说直接上代码 :

public class Demo {
	public static void main(String[] args){
		String s1 = "123";
		String s2 = "123";
		String s3 = new String("123");
		System.out.println(s1==s2);//输出 true
		System.out.println(s3==s1);//输出 false
	}
}

上述代码,

    首先简单了解一下栈 和 常量池:

    1>.栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中)。

    2>.常量池:存放字符串常量和基本类型常量( public static final ,java存放字符串用 public final 修饰的value数组 )

s1,s2都是常量,其后面的 "123" 都被放在常量池中,其实在 s2 创建的时候,只是把已经在常量池中的 "123"赋值给了s1引用变量,这样s1当然等于s2啦,因为两者是一个东西,当然地址也相同。

至于s3为什么不等于s1,那是因为,s3是new出来的,也就是说s3new出来的对象在堆中,s3这个引用变量在栈中,但是s1的对象在常量池中,这两个当然地址不一样啦!


2. equals方法 

    1>.首先上未经重写的equals源码,也就是Object中的 equals 方法:

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

上述代码,大家不难看出,要比较两个引用变量所指对象的地址。

    2>.接下来,上String类型重写过后的equals方法:

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

由上述代码不难看出,首先java 先比较两个字符串的地址是否相同,如果相同,那么就直接返回true;

接下来,如果地址不相同,那么分别获取两个字符串对应的 char 数组,进行遍历比较每个字符是否相等,如果有一个不相等就返回false,否则就返回true。

注意:java已经将大部分类都重写了equals方法!!! 只有少部分不需要用到equals的,才没重写。


3.hashcode() 方法

写这个之前,我先说一下我之前遇到的一个小问题:

public class Demo {
	public static void main(String[] args){
		String a= null;
		System.out.println(a.hashCode());
	} 
}

这段代码报错 

Exception in thread "main" java.lang.NullPointerException
	at ttms.Demo.main(Demo.java:6)
之后我找到了String类重写的 hashCode() 的源码:
  public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

上述代码中会调用 value.length变量,value就是你的字符串转换成的字符数组,那么问题就简单了,你传进去的对象就是空的,那就肯定没有length属性啦,也就会报空指针异常。

补充一下:如果没有重写hashcode方法,那么就返回的是对象的32位jvm内存地址。




    



©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页