==和equals()的区别、hashCode()、为什么重写equals()方法必须重写hashCode()

==运算符

1.基本数据类型

基本数据类型进行值的比较

public class Test09 {
     
	public static void main(String[] args) {
     
		int number1 = 5;
		int number2 = 3;
		int number3 = 5;
		System.out.println(number1==number2);  //false
		System.out.println(number1==number3);  //true
	}
}

1.引用数据类型

对于引用类型来说,==比较的是双方的内存地址,相同返回true否则返回false。

以String类型举例

public class Test10 {
     
	public static void main(String[] args) {
     
		String str01 = "just do it";
		String str02 = "just"+" do it";
		String str03 = "just";

		System.out.println(str01 == str02);// true
		System.out.println(str01 == str03);//false
	}
}

equals()方法

1.基本数据类型没有equals()方法

2.引用数据类型

引用数据类型进行值或内容的比较,由于字符串内部是由char[] 数组存储的,所一实际上比较的是字符数组。

JDK8 String内部是由char[]保存的,但在JDK9则是用byte[]进行保存的
以String为例:

1.未重写父类Object的equals()方法

默认使用父类Object的equals方法

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

可以看出父类的equals方法比较的是双方的内存地址(相同返回true,否则返回false)

2.重写父类的equals()方法

以下是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;
    }

String重写父类方法的逻辑:

1.首先比较双方的内存地址,相同返回true,否则向下执行。

2.其次比较双方的长度,不相同则退出if语句并返回false,相同则向下执行。

3.最后比较双方的内容,若存在不同的元素则返回false,否则继续执行,直到最后退出循环,最后返回true。

值得一提的是重写equals()方法必须重写hashCode()
首先介绍hashCode()

hashCode()

hashCode()是Object类中的native本地方法,底层通过使用C/C++来实现,用于获取对象的HashCode哈希码。

HashCode哈希码是该对象的内存地址通过哈希hash算法计算出的一个整数值,代表该对象在哈希表中的位置,作用是为了提高查找对象的快捷性,通过HashCode可以快速定位对象的存储地址。

俩个对象进行比较,先通过HashCode进行比较,若HashCode相等(俩个不同的对象hashCode可能会相同,只不过概率特别小),再调用equals()方法进行比较,以此提高效率。

重写equals()方法必须重写hashCode()

俩个对象进行比较,先通过HashCode值进行比较,若HashCode值相等,再调用equals()方法进行比较,以此提高效率。

1.如果俩个对象相同,说明它俩的hashCode值一定相同

2.如果俩个对象的hashCode相同,他们并不一定相同(所以需要使用equals进行比较),例如:字符串 “重地” 与 “通话” hashCode值相同。

public class Test11 {
     
	public static void main(String[] args) {
     
		String str01 = "通话";
		String str02 = "重地";
		System.out.println("str01的哈希码是:"+str01.hashCode());
		System.out.println("str02的哈希码是:"+str02.hashCode());
	}
}

运行结果:
在这里插入图片描述
所以,在每个equals()方法的类中,也必须覆盖hashCode()方法,否则会违反Object.hashCode的通用约定,从而导致无法结合基于散列的集合在一起正常运作,例如:HashMap,HashSet和HashTable等集合。

Object.hashCode的通用约定

  1. 在应用程序中,只要对象的euqals方法的比较操作所用的信息没有修改,那么对于同一个对象的调用多次hashCode,必须始终如一返回同一个哈希值。
  2. 如果两个对象通过equals比较相等,那么它们的哈希值相同。
  3. 如果两个对象通过euqals比较不等,他们的哈希值可能相同,取决于hashCode的实现,由此散列表的性能也会有区别。

以上就是==和equals()的区别、hashCode()、为什么重写equals()方法必须重写hashCode()的全部内容,如有不当请大家多多指正,一起进步!!!

你可能感兴趣的:(学习心得,java)