1、概念
1、操作数的值
String str1;
这句话声明了一个引用类型的变量,此时它并没有和任何对象关联。 而通过 new 来产生一个对象,并将这个对象和str1进行绑定:
str1= new String("hello");
那么 str1 就指向了这个对象,此时引用变量str1中存储的是它指向的对象在内存中的存储地址,并不是“值”本身,也就是说并不是直接存储的字符串”hello”。这里面的引用和 C/C++ 中的指针很类似。
2、小结
因此,对于关系操作符 ==:
1、来源 equals方法是基类Object中的实例方法,因此对所有继承于Object的类都会有该方法。 在 Object 中的声明:
public boolean equals(Object obj) {}
2、equals方法的作用 初衷 : 判断两个对象的 content 是否相同
为了更直观地理解equals方法的作用,我们先看Object类中equals方法的实现。
public boolean equals(Object obj) {
return (this == obj);
}
很显然,在Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。
但我们都知道,下面代码输出为 true:
public class Main {
public static void main(String[] args) {
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1.equals(str2));
}
}
原来是 String 类重写了 equals 方法:
public boolean equals(Object anObject) { // 方法签名与 Object类 中的一致
if (this == anObject) { // 先判断引用是否相同(是否为同一对象),
return true;
}
if (anObject instanceof String) { // 再判断类型是否一致,
// 最后判断内容是否一致.
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
即对于诸如“字符串比较时用的什么方法,内部实现如何?”之类问题的回答即为:
使用equals方法,内部实现分为三个步骤:
Java 中所有内置的类的 equals 方法的实现步骤均是如此,特别是诸如 Integer,Double 等包装器类。
3、equals 重写原则
对象内容的比较才是设计equals()的真正目的,Java语言对equals()的要求如下,这些要求是重写该方法时必须遵循的:
4、小结 因此,对于 equals 方法:
1、hashCode 的来源 hashCode 方法是基类Object中的 实例native方法,因此对所有继承于Object的类都会有该方法。 在 Object类 中的声明(native方法暗示这些方法是有实现体的,但并不提供实现体,因为其实现体是由非java语言在外面实现的):
public native int hashCode();
2、哈希相关概念 我们首先来了解一下哈希表:
图1 哈希表示例 左边很明显是个数组,数组的每个成员是一个链表。该数据结构所容纳的所有元素均包含一个指针,用于元素间的链接。我们根据元素的自身特征把元素分配到不同的链表中去,也是根据这些特征,找到正确的链表,再从链表中找出这个元素。其中,将根据元素特征计算元素数组下标的方法就是散列法。
3、hashCode 简述 在 Java 中,由 Object 类定义的 hashCode 方法会针对不同的对象返回不同的整数。(这是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧)。
hashCode 的常规协定是:
4、equals 与 hashCode
前提: 谈到hashCode就不得不说equals方法,二者均是Object类里的方法。由于Object类是所有类的基类,所以一切类里都可以重写这两个方法。
5、实现例证
hashCode()在object类中定义如下:
public native int hashCode();
说明是一个本地方法,它的实现是根据本地机器相关的。
String 类是这样重写它的:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
/** The value is used for character storage. */
private final char value[]; //成员变量1
/** The offset is the first index of the storage that is used. */
private final int offset; //成员变量2
/** The count is the number of characters in the String. */
private final int count; //成员变量3
/** Cache the hash code for the string */
private int hash; // Default to 0 //非成员变量
public int hashCode() {
int h = hash;
int len = count; //用到成员变量3
if (h == 0 && len > 0) {
int off = offset; //用到成员变量2
char val[] = value; //用到成员变量1
for (int i = 0; i < len; i++) {
h = 31*h + val[off++]; //递推公式
}
hash = h;
}
return h;
}
}
对程序的解释: h = s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1],由此可以看出,对象的hash地址不一定是实际的内存地址。
引用:
浅谈Java中的equals和== 从头到尾彻底解析哈希表算法 java中hashCode方法与equals方法的用法总结 java中的hashCode方法小例子 JAVA hashCode使用方法详解 Java equals 方法与hashcode 方法的深入解析 详解Java中用于查找对象哈希码值的hashCode()函数