1.演算子==
Javaのデータ型は、基本データ型(byte、short、char、int、long、float、double、boolean)と参照データ型(クラス、インターフェイス、および配列)の2つのカテゴリに分類されます。
- 基本データ型
基本データ型では、==操作は2つの変数の値が等しいかどうかを比較します。 - 参照データ型
参照データ型では、==操作はメモリ内の2つのオブジェクトの参照アドレスを比較します。参照型はオブジェクト参照(アドレス)をスタックに格納し、オブジェクトはヒープに格納されます。
2.等しい方法
equalsは、デフォルトでObjectクラスによって提供されるメソッドです。
オブジェクトのメモリアドレスが同じアドレスであるかどうか(同じオブジェクトであるかどうか)を判断するために、主にカバレッジは使用されません。
// Object 类equals 源码
public boolean equals(Object obj) {
return (this == obj);
}
- カバレッジ状況
equalsメソッドがカバーされている場合、equalsメソッドの機能は特定のコードに従って決定されます。一般に、オブジェクトが等しいかどうかは、オブジェクトの内容が等しいかどうかによって判断されます。
// String 类 equals 源码
public boolean equals(Object anObject) {
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;
}
判断相等的步骤:
1. 比较两个String对象是否为同一对象,如果是就直接返回true
2. 如果不是同一对象,先确定传入的对象是否是String类型,如果是,则比较两对象的字符序列
3. 遍历过程中只要有一个字符不相同,就返回false,否则返回true
補足:カバーすることは、一般的な慣習に準拠する必要があります
- 再帰性:null以外の参照値xの場合、x.equals(x)はtrueを返す必要があります
- 対称性:null以外の参照値xおよびyの場合、y.equals(x)がtrueを返す場合に限り、x.equals(y)はtrueを返す必要があります
- 推移性:null以外の参照値x、y、zの場合、x.equals(y)がtrueで、y.equals(z)もtrueを返す場合、x.equals(z)もtrueを返す必要があります
- 一貫性:null以外の参照値xおよびyの場合、等しい比較操作のオブジェクトで使用される情報が変更されていない限り、x.equals(y)への複数の呼び出しは一貫してtrueまたはfalseを返します
- null以外の参照値xの場合、x.equals(null)はfalseを返す必要があります
3.HashCode
hashCodeメソッドの戻り値はInt型データであり、この値はハッシュコード(ハッシュコード)と呼ばれます。役割:ハッシュテーブル内のオブジェクトのインデックス位置を決定します。
// Object 类的源码
public native int hashCode();
応用
Javaでは、コレクションは大量のデータを格納できるため、Setコレクション内の要素は順序付けられておらず、繰り返し不可です。では、Setコレクションはどのようにして要素が繰り返されないようにしますか?反復を通じてequals()が等しいかどうかを確認します。少量のデータでもかまいませんが、大量のデータがあると効率が想像できます。hashCodeがソリューションを提供します。
HashCodeはローカルメソッドであり、その実装はローカルマシンに関連しています。コレクションに要素を追加すると、コレクションは最初にhashCodeメソッドを呼び出して、保存されている場所に直接配置できるようにします。他の要素がない場合は、直接保存されます。そこにすでに要素が存在する場合、equalsメソッドが呼び出されて、2つの要素が同じであるかどうかが一致し、同じものは存在せず、差は別の場所にハッシュされます。このように、多数の要素を格納する場合、equals()メソッドの呼び出し回数を大幅に減らすことができ、効率が大幅に向上します。
hashCodeメソッドとequalsメソッドの関係
たとえば、Javaでは、HashMap、HashSet、HashTableなどのコレクションフレームワークを使用する場合、HashMapのキーとして独自の新しいクラスを使用します。この場合、hashCodeおよびequalsメソッドを書き直す必要があります。
例
public class EqHashCode {
public static void main(String[] args) {
Student stu=new Student("小米","一班");
Student stu1=new Student("小米","一班");
HashMap<Student, String> hashMap = new HashMap<>();
hashMap.put(stu,stu.className);
hashMap.put(stu1,stu1.className);
System.out.println(hashMap.size());
System.out.println(stu==stu1);
System.out.println(stu.equals(stu1));
}
}
public class Student {
public String name;
public String className;
public Student(String name, String className) {
super();
this.name = name;
this.className = className;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Student) {
Student stu = (Student) obj;
if (name.equals(stu.name) && className.equals(stu.className)) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
int result = 17;// 非0 任选
result = 31 * result + name.hashCode();
result = 31 * result + className.hashCode();
return result;
}
}
运行结果:
第一次equals 方法没有覆盖情况下,hashMap size为2;第二次覆盖equals 方法下,hashMap size为1
総括する
- 2つのオブジェクトが等しい場合、ハッシュコードも同じである必要があります
- 2つのオブジェクトが等しい場合、2つのオブジェクトのequalsメソッドはそれぞれtrueを返します
- 2つのオブジェクトは同じハッシュコード値を持ち、必ずしも等しいとは限りません
- equalsメソッドはオーバーライドされ、hashCodeメソッドもオーバーライドされる必要があります
- hashCode()のデフォルトの動作は、ヒープ上のオブジェクトに対して一意の値を生成することです。hashCode()がオーバーライドされない場合、このクラスの2つのオブジェクトはとにかく等しくなりません(2つのオブジェクトが同じデータを指している場合でも)
参照
ハッシュコードをオーバーライドして等しいので、hashCodeメソッドをオーバーライドする必要があります。なぜ等しいを書き換えるのですか?