[equals メソッド] 関連の問題

1. == と等しいの違いは何ですか?

==:
基本的なデータ型の場合、== は値を比較します。
参照データ型の場合、== はオブジェクトのメモリ アドレスを比較します。

Java は値による転送のみを行うため、== の場合、基本データ型を比較す​​る場合でも、参照データ型の変数を比較する場合でも、比較の本質は値ですが、参照型変数に格納される値はオブジェクトのアドレスです。

等しい:
equals() の関数は、基本データ型の変数を判定するために使用することはできません。2 つのオブジェクトが等しいかどうかを判定するためにのみ使用できます。equals() メソッドは、すべてのクラスの直接的または間接的な親クラスである Object クラスに存在します。
このクラスは、equals() メソッドをオーバーライドしません。equals () を使用してこのクラスの 2 つのオブジェクトを比較する場合、「==」を使用して 2 つのオブジェクトを比較するのと同等であり、デフォルトは Object クラスの equals() メソッドです。 。
このクラスは、equals() メソッドをオーバーライドします。通常、equals() メソッドをオーバーライドして、2 つのオブジェクトのプロパティが等しいかどうかを比較します。プロパティが等しい場合は、true を返します (つまり、2 つのオブジェクトは等しいとみなされます)。

public class test1 {
    
    
    public static void main(String[] args) {
    
    
        String a = new String("ab"); // a 为一个引用
        String b = new String("ab"); // b为另一个引用,对象的内容一样
        String aa = "ab"; // 放在常量池中
        String bb = "ab"; // 从常量池中查找
        if (aa == bb) // true
            System.out.println("aa==bb");
        if (a == b) // false,非同一对象
            System.out.println("a==b");
        if (a.equals(b)) // true
            System.out.println("aEQb");
        if (42 == 42.0) {
    
     // true
            System.out.println("true");
        }
    }
}

Object の等しいメソッドはオブジェクトのメモリ アドレスを比較し、String の等しいメソッドはオブジェクトの値を比較するため、String の等しいメソッドはオーバーライドされます。

String 型のオブジェクトを作成する場合、仮想マシンは定数プールを調べて、作成するオブジェクトと同じ値を持つオブジェクトがあるかどうかを確認し、ある場合はそれを現在の参照に割り当てます。そうでない場合は、定数プールに String オブジェクトを再作成します。

== 基本型の場合は値の比較、参照型の場合は参照比較、equals はデフォルトで参照比較ですが、多くのクラスは String や Integer などのquals メソッドを書き換えて変更します。 to Value 比較なので、一般に、equals は値が等しいかどうかを比較します。

2. hashCode()とequals()

1. hashCode() の関数:

hashCode() はハッシュ コード (ハッシュ コードとも呼ばれる) を取得することであり、実際には int を返します。このハッシュ コードの機能は、ハッシュ テーブル内のオブジェクトのインデックス位置を決定することです。hashCode() は JDK の Object クラスで定義されます。つまり、Java のすべてのクラスに hashCode() 関数が含まれます。また、Object の hashcode メソッドは C 言語または C++ で実装されるローカル メソッドであり、通常、このメソッドはオブジェクトのメモリ アドレスを整数に変換して返すために使用されます。

public native int hashCode();

ハッシュテーブルにはキーと値のペア(キーバリュー)が格納されており、「キー」に応じて対応する「値」を高速に取得できるのが特徴です。ここでハッシュコードが使用されます。(目的のオブジェクトをすぐに見つけることができます)

2. なぜハッシュコードがあるのですか?

HashSet にオブジェクトを追加すると、HashSet はまずオブジェクトのハッシュコード値を計算してオブジェクトが追加される場所を決定し、さらに追加された他のオブジェクトのハッシュコード値と比較します。ハッシュコードが一致すると、HashSet はオブジェクトが重複していないとみなします。ただし、同じハッシュコード値を持つオブジェクトが見つかった場合は、equals() メソッドが呼び出され、同じハッシュコードを持つオブジェクトが本当に同じかどうかがチェックされます。2 つが同じ場合、HashSet は結合操作を成功させません。異なる場合は、別の場所に再ハッシュされます。このようにして、等しい数が大幅に減り、実行速度が大幅に向上します。

3. 等しいものを書き換えるときに hashCode メソッドを書き換える必要があるのはなぜですか?

2 つのオブジェクトが等しい場合、ハッシュコードも同じでなければなりません。2 つのオブジェクトが等しい場合、2 つのオブジェクトに対して equals メソッドを呼び出すと true が返されます。ただし、同じハッシュコード値を持つ 2 つのオブジェクトが必ずしも等しいとは限りません。したがって、equals メソッドをオーバーライドする場合は、hashCode メソッドもオーバーライドする必要があります。

hashCode() のデフォルトの動作は、ヒープ上のオブジェクトに対して一意の値を生成することです。hashCode() がオーバーライドされない場合、このクラスの 2 つのオブジェクトは等しくありません (2 つのオブジェクトが同じデータを指している場合でも)。

4. 2 つのオブジェクトが同じ hashCode 値を持っているのに、必ずしも等しいわけではないのはなぜですか?

「call」と「heavy ground」の hashCode() は同じですが、ハッシュ テーブルでは hashCode() が等しい、つまり 2 つのキーのハッシュ値が等しいため、equals() は false になります。 -value ペアは等しいですが、ハッシュ値は等しいため、必ずしも key-value ペアが等しいと結論付けることはできません。

hashCode() で使用されるハッシュ アルゴリズムにより、複数のオブジェクトが同じハッシュ値を返す可能性があるためです。ハッシュ アルゴリズムが悪いほど衝突しやすくなりますが、これはデータ値フィールドの分布の特性にも関係します (いわゆる衝突とは、異なるオブジェクトが同じ hashCode を取得することを意味します)。

先ほど HashSet についても触れましたが、比較時に HashSet に同じハッシュコードを持つオブジェクトが複数ある場合、equals() を使用してそれらが本当に同じかどうかを判断します。つまり、ハッシュコードは検索コストを削減するためにのみ使用されます。

3.equals()メソッドを使用するとnullポインタが表示される

equals() を使用すると、メソッドが null 値で呼び出されるために、null ポインタ例外が報告されます。null ではメソッドを呼び出すことができないことに注意してください。equals を使用する場合は、最初に値の有効性を検証する必要があります。または、定数を使用して、equals() メソッドを呼び出します。

元:

public static void main(String[] args) {
    
    
    User user = new User();
    user.setName("王二");

    User user2 = new User();
    user2.setAge(18);

    if (user.getName().equals(user2.getName())){
    
     //user.getName()不是null,则不会报空指针异常
        System.out.println("是王二");
    }
    
    if("王二".equals(user.getName())){
    
     //使用常量去调用equals()方法,也不会报空指针异常
        System.out.println("是王二");
    }
}

4.equals()とindexof()、contains()の使用法

equals(): 2 つの文字列が等しいかどうかを判断します;
IndexOf() および Contains(): 指定された文字列が文字列に含まれるかどうかを判断し、IndexOf() と Contains() は両方とも大文字と小文字を区別します

1. IndexOf() メソッドと Contains() メソッドでは大文字と小文字が区別されません。

IndexOf() メソッドには、大文字と小文字を区別しないように設定できる組み込みパラメータ StringComparison.OrdinalIgnoreCase があります。

string str1="Abc";  string str2="abc";
str1.IndexOf(str2,StringComparison.OrdinalIgnoreCase);

Contains() メソッドは、大文字と小文字を区別しないようにするために、最初に文字列を大文字または小文字に変換することしかできません。

string str1="Abc";  string str2="abc";
str1.ToUpper().Contains(str2.ToUpper());

2. マッチング効率:

大文字と小文字を区別する場合、Contains() メソッドは IndexOf() メソッドより効率的です。
大文字と小文字を区別しない場合、IndexOf() メソッドは Contains() メソッドより効率的です。

3. 戻り値の型:

IndexOf() メソッドは、指定された文字列を含む最初の添え字を返します。添え字は 0 から始まり、含まれていない場合は -1 を返します。
Contains() メソッドは、指定された文字列が含まれている場合は true を返し、含まれていない場合は false を返します。

おすすめ

転載: blog.csdn.net/m0_46459413/article/details/131324096