作者:杰仔 | 来源:互联网 | 2023-09-25 09:07
对于String类和各种包装类(Integer等):
首先强调:
对于两个对象 equals()返回为true → hashcode()必然相同;
但这规律并不是什么所谓的不变的公理,它无非是源码实现出来的结果,一致遵从的契约。
当你想改变这规则时,直接覆写掉equals()和hashcode()函数即可,但最好还是遵从java源码的规则进行覆写,不要随心所欲。
- 字符串源码的equals()实现:
先比较的是它的内存值,然后比较的是它内容;对于包装类源码的equals()实现:直接比较的是内容。源码如下↓
public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String aString = (String)anObject;if (!COMPACT_STRINGS || this.coder == aString.coder) {return StringLatin1.equals(value, aString.value);}}return false;}
- 在字符串和包装类java源码的实现中,将equals覆写了,同时也将hashcode()覆写了(并且将键值通过某一函数映射为哈希值),实现了在equals相等时,它的hash值必然相等。
- 但要注意的是字符串和包装类的对象hash值和内存值并不相等(因为这时的hash值已经变成了这时候内容的映射)。
其实对于其他的各种对象来说,都不要将new出来的对象引用值和hashcode的值混为一谈,new出来的对象引用实际上是指向其堆内存的一个指针;而hashcode的值是使用某一哈希函数,针对不同的对象返回不同的整数值。
不要将==理解为对于hash值的比较,它是对于堆内存引用值的比较!
例子:
- 对于String类型的字符串以及各种包装类来说:
public class A {public static void main(String[] args) {String s1 = "hello";String s2 = "hello";String s3 = new String("hello");System.out.println(s1 == s2);System.out.println(s1 == s3);System.out.print(s1.equals(s3));}
}
输出结果:
-
对于基本数据类型来说:
直接用==比较值,不能用.equals()。
-
其他情况:
https://www.cnblogs.com/weibanggang/p/9457757.html
总结:
- 基本数据类型的比较使用==,不能使用.equals();
- 引用数据类型的比较,可以使用==或者.equals(),==比较的是内存值,.equals()比较的是内容值。