私はこれを正しく理解しているかどうかを明確にしたかった:
==
は参照比較です。つまり、両方のオブジェクトが同じメモリ位置を指します.equals()
オブジェクトの値の比較に評価されます
私はこれを正しく理解しているかどうかを明確にしたかった:
==
は参照比較です。つまり、両方のオブジェクトが同じメモリ位置を指します.equals()
オブジェクトの値の比較に評価されます一般的に、あなたの質問に対する答えは「はい」ですが...
.equals(...)
比較するために書かれたものだけを比較し、それ以上でもそれ以下でもありません。equals(Object o)
このメソッドをオーバーライドした最も近い親クラスのメソッドになります。Object#equals(Object o)
メソッドが残ります。Object APIによると、これは==
;と同じです。つまり、両方の変数が同じオブジェクトを参照している場合にのみ、それらの参照が同じである場合にtrueを返します。したがって、機能の同等性ではなく、オブジェクトの同等性をテストします。hashCode
する場合は、常にオーバーライドすることを忘れないでください。equals
APIによると、hashCode()
2つのオブジェクトのメソッドから返される結果は、それらのメソッドが同等であることが示されている場合、同じである必要があります。equals
その逆は必ずしも真実ではありません。Stringクラスに関して:
equals()メソッドは、2つのオブジェクト参照が同じStringインスタンスを参照しているかどうかに関係なく、(ヒープ上の)Stringインスタンス内の「値」を比較します。String型の2つのオブジェクト参照が同じStringインスタンスを参照している場合は、すばらしいです。2つのオブジェクト参照が2つの異なるStringインスタンスを参照している場合、違いはありません。比較されている各Stringインスタンス内の「値」(つまり、文字配列の内容)。
一方、 "=="演算子は、 2つのオブジェクト参照の値を比較して、それらが同じStringインスタンスを参照しているかどうかを確認します。両方のオブジェクト参照の値が同じStringインスタンスを「参照」する場合、ブール式の結果は「true」になります。一方、両方のオブジェクト参照の値が異なるStringインスタンスを「参照」する場合(両方のStringインスタンスが同じ「値」を持っている場合、つまり、各Stringインスタンスの文字配列の内容が同じである場合でも)ブール式の結果は「false」になります。
他の説明と同様に、それを沈めましょう。
これで少し問題が解決することを願っています。
「プリミティブ」と「オブジェクトタイプ」のどちらについて話しているかによって、いくつかの小さな違いがあります。「静的」または「非静的」メンバーについて話している場合も同じことが言えます。上記のすべてを混ぜることもできます...
次に例を示します(実行できます)。
public final class MyEqualityTest
{
public static void main( String args[] )
{
String s1 = new String( "Test" );
String s2 = new String( "Test" );
System.out.println( "\n1 - PRIMITIVES ");
System.out.println( s1 == s2 ); // false
System.out.println( s1.equals( s2 )); // true
A a1 = new A();
A a2 = new A();
System.out.println( "\n2 - OBJECT TYPES / STATIC VARIABLE" );
System.out.println( a1 == a2 ); // false
System.out.println( a1.s == a2.s ); // true
System.out.println( a1.s.equals( a2.s ) ); // true
B b1 = new B();
B b2 = new B();
System.out.println( "\n3 - OBJECT TYPES / NON-STATIC VARIABLE" );
System.out.println( b1 == b2 ); // false
System.out.println( b1.getS() == b2.getS() ); // false
System.out.println( b1.getS().equals( b2.getS() ) ); // true
}
}
final class A
{
// static
public static String s;
A()
{
this.s = new String( "aTest" );
}
}
final class B
{
private String s;
B()
{
this.s = new String( "aTest" );
}
public String getS()
{
return s;
}
}
次のリンクから、「==」(等号演算子)と「.equals(...)」(java.lang.Objectクラスのメソッド)の説明を比較できます。
==とequalsの違いは、私がそれを詳しく調べることにするまで、しばらくの間私を混乱させました。それらの多くは、文字列を比較するためequals
に、ではなく使用する必要があると言ってい==
ます。この答えで私は違いを言うことができることを願っています。
この質問に答える最良の方法は、自分自身にいくつか質問することです。それでは始めましょう:
以下のプログラムの出力は何ですか。
String mango = "mango";
String mango2 = "mango";
System.out.println(mango != mango2);
System.out.println(mango == mango2);
あなたが言うなら、
false
true
私はあなたが正しいと言いますが、なぜあなたはそれを言ったのですか?そして、あなたが出力がであると言うならば、
true
false
私はあなたが間違っていると言いますが、それでもあなたに尋ねます、なぜあなたはそれが正しいと思いますか?
わかりました、これに答えてみましょう:
以下のプログラムの出力は何ですか。
String mango = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango3);
System.out.println(mango == mango3);
今あなたが言うなら、
false
true
私はあなたが間違っていると言いますが、なぜ今それは間違っているのですか?このプログラムの正しい出力は次のとおりです。
true
false
上記のプログラムを比較して考えてみてください。
Ok。これが役立つかもしれません(これを読んでください:オブジェクトのアドレスを出力してください-不可能ですが、それでも使用できます)。
String mango = "mango";
String mango2 = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(mango3 != mango2);
System.out.println(mango3 == mango2);
// mango2 = "mang";
System.out.println(mango+" "+ mango2);
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(System.identityHashCode(mango));
System.out.println(System.identityHashCode(mango2));
System.out.println(System.identityHashCode(mango3));
上記のコードの最後の3行の出力について考えてみてください:私にとっては、ideoneがこれを印刷しました(ここでコードを確認できます):
false
true
true
false
mango mango
false
true
17225372
17225372
5433634
おー!これで、identityHashCode(mango)がidentityHashCode(mango2)と等しいことがわかりますが、identityHashCode(mango3)と等しくありません。
すべての文字列変数(mango、mango2、mango3)の値は同じですが、「mango」はすべての文字列で同じでidentityHashCode()
はありません。
ここで、この行のコメントを外してもう一度実行してみてください。今回は、3つすべてが異なる// mango2 = "mang";
ことがわかります。identityHashCode()
うーん、それは役に立つヒントです
if hashcode(x)=N
and hashcode(y)=N
=>x is equal to y
Javaが内部でどのように機能するかはわかりませんが、次のように言ったときにこれが起こったと思います。
mango = "mango";
javaは、次のような"mango"
変数によってポイント(参照)される文字列を作成しましたmango
mango ----> "mango"
今私が言った次の行で:
mango2 = "mango";
実際には、"mango"
次のような同じ文字列を再利用しました
mango ----> "mango" <---- mango2
mangoとmango2の両方が同じ参照を指している今私が言ったとき
mango3 = new String("mango")
実際には、「mango」のまったく新しい参照(文字列)が作成されました。このように見えます、
mango -----> "mango" <------ mango2
mango3 ------> "mango"
そのため、の値を出力するとmango == mango2
、が出力されtrue
ます。そして、の値を出すと、mango3 == mango2
(false
同じ値でも)出します。
行のコメントを外すと、// mango2 = "mang";
実際には文字列「mang」が作成され、グラフが次のようになります。
mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"
これが、identityHashCodeがすべてで同じではない理由です。
これが皆さんのお役に立てば幸いです。実際、==が失敗し、equals()が合格するテストケースを生成したかったのです。コメントして、間違っている場合はお知らせください。
==演算子は、2つの変数が同じ参照(メモリアドレスへのポインタ)を持っているかどうかをテストします。
String foo = new String("abc");
String bar = new String("abc");
if(foo==bar)
// False (The objects are not the same)
bar = foo;
if(foo==bar)
// True (Now the objects are the same)
一方、equals()メソッドは、2つの変数が同じ状態(値)を持つオブジェクトを参照しているかどうかをテストします。
String foo = new String("abc");
String bar = new String("abc");
if(foo.equals(bar))
// True (The objects are identical but not same)
乾杯 :-)
カスタムクラスでこれを使用するには、equals関数を(他の関数とともに)オーバーライドする必要があります。
equalsメソッドはオブジェクトを比較します。
二==
項演算子はメモリアドレスを比較します。
==
は演算子でありequals()
、はメソッドです。
演算子は一般にプリミティブ型の比較に==
使用されるため、メモリアドレスの比較に使用され、equals()
メソッドはオブジェクトの比較に使用されます。
.equals()をオーバーライドしない場合、==と.equals()の両方が同じオブジェクトを参照します。
.equals()をオーバーライドしたら、何をしたいのかがあなたの願いです。呼び出し元のオブジェクトの状態を渡されたオブジェクトの状態と比較するか、super.equals()を呼び出すだけです。
String w1 ="Sarat";
String w2 ="Sarat";
String w3 = new String("Sarat");
System.out.println(w1.hashCode()); //3254818
System.out.println(w2.hashCode()); //3254818
System.out.println(w3.hashCode()); //3254818
System.out.println(System.identityHashCode(w1)); //prints 705927765
System.out.println(System.identityHashCode(w2)); //prints 705927765
System.out.println(System.identityHashCode(w3)); //prints 366712642
if(w1==w2) // (705927765==705927765)
{
System.out.println("true");
}
else
{
System.out.println("false");
}
//prints true
if(w2==w3) // (705927765==366712642)
{
System.out.println("true");
}
else
{
System.out.println("false");
}
//prints false
if(w2.equals(w3)) // (Content of 705927765== Content of 366712642)
{
System.out.println("true");
}
else
{
System.out.println("false");
}
//prints true
.equals(...)
比較しようとしているクラスによって実装される必要があることを覚えておいてください。そうでなければ、あまり意味がありません。Objectクラスのメソッドのバージョンは、比較操作と同じことを行います:Object#equals。
オブジェクトに対して比較演算子を実際に使用したいのは、列挙型を比較しているときだけです。これは、一度にEnum値のインスタンスが1つしかないためです。たとえば、列挙型が与えられた
enum FooEnum {A, B, C}
一度に複数のインスタンスを持つことは決してなく、とについてもA
同じです。これは、実際には次のようなメソッドを記述できることを意味します。B
C
public boolean compareFoos(FooEnum x, FooEnum y)
{
return (x == y);
}
そして、あなたは何の問題もありません。
relational operator ==
との違いの一般的なルールは次のとおりですthe method .equals()
。
object1 == object2
object1とobject2によって参照されるオブジェクトがヒープ内の同じメモリ位置を参照しているかどうかを比較します。
object1.equals(object2)
メモリー内のどこにあるかに関係なく、object1とobject2の値を比較します。
これは、Stringを使用してうまく示すことができます
シナリオ1
public class Conditionals {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = new String("Hello");
System.out.println("is str1 == str2 ? " + (str1 == str2 ));
System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
}
}
The result is
is str1 == str2 ? false
is str1.equals(str2) ? true
シナリオ2
public class Conditionals {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
System.out.println("is str1 == str2 ? " + (str1 == str2 ));
System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
}
}
The result is
is str1 == str2 ? true
is str1.equals(str2) ? true
この文字列の比較は、他のタイプのオブジェクトを比較するための基礎として使用できます。
たとえば、Personクラスがある場合、 2人の人物を比較する基準を定義する必要があります。このpersonクラスにheightとweightのインスタンス変数があるとしましょう。
したがって、personオブジェクトperson1 and person2
を作成し、これら2つを使用して比較するには、personクラスのequalsメソッド.equals()
をオーバーライドして、比較対象のインスタンス変数(heighまたはweight)に基づいて定義する必要があります。
ただし、== operator will still return results based on the memory location of the two objects(person1 and person2)
。
この人物オブジェクトの比較を一般化するために、次のテストクラスを作成しました。これらの概念を実験すると、たくさんの事実が明らかになります。
package com.tadtab.CS5044;
public class Person {
private double height;
private double weight;
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(height);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
/**
* This method uses the height as a means of comparing person objects.
* NOTE: weight is not part of the comparison criteria
*/
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (Double.doubleToLongBits(height) != Double.doubleToLongBits(other.height))
return false;
return true;
}
public static void main(String[] args) {
Person person1 = new Person();
person1.setHeight(5.50);
person1.setWeight(140.00);
Person person2 = new Person();
person2.setHeight(5.70);
person2.setWeight(160.00);
Person person3 = new Person();
person3 = person2;
Person person4 = new Person();
person4.setHeight(5.70);
Person person5 = new Person();
person5.setWeight(160.00);
System.out.println("is person1 == person2 ? " + (person1 == person2)); // false;
System.out.println("is person2 == person3 ? " + (person2 == person3)); // true
//this is because perosn3 and person to refer to the one person object in memory. They are aliases;
System.out.println("is person2.equals(person3) ? " + (person2.equals(person3))); // true;
System.out.println("is person2.equals(person4) ? " + (person2.equals(person4))); // true;
// even if the person2 and person5 have the same weight, they are not equal.
// it is because their height is different
System.out.println("is person2.equals(person4) ? " + (person2.equals(person5))); // false;
}
}
このクラスの実行結果は次のとおりです。
is person1 == person2 ? false
is person2 == person3 ? true
is person2.equals(person3) ? true
is person2.equals(person4) ? true
is person2.equals(person4) ? false
コードを評価すると、(==)がメモリアドレスに従って比較され、equals(Object o)がインスタンスのhashCode()を比較することは非常に明白です。そのため、後で驚きに直面しない場合は、equals()とhashCode()の間のコントラクトを破らないでください。
String s1 = new String("Ali");
String s2 = new String("Veli");
String s3 = new String("Ali");
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
System.out.println("(s1==s2):" + (s1 == s2));
System.out.println("(s1==s3):" + (s1 == s3));
System.out.println("s1.equals(s2):" + (s1.equals(s2)));
System.out.println("s1.equal(s3):" + (s1.equals(s3)));
/*Output
96670
3615852
96670
(s1==s2):false
(s1==s3):false
s1.equals(s2):false
s1.equal(s3):true
*/
==とequals()の主な違いは次のとおりです。
1)==はプリミティブを比較するために使用されます。
例えば :
String string1 = "Ravi";
String string2 = "Ravi";
String string3 = new String("Ravi");
String string4 = new String("Prakash");
System.out.println(string1 == string2); // true because same reference in string pool
System.out.println(string1 == string3); // false
2)equals()は、オブジェクトを比較するために使用されます。例えば :
System.out.println(string1.equals(string2)); // true equals() comparison of values in the objects
System.out.println(string1.equals(string3)); // true
System.out.println(string1.equals(string4)); // false
また、2つのオブジェクトが等しいかどうかをテストする場合、これが最初にテストしたいものであるため、.equals()
通常はテスト用に含まれていることに注意してください。==
そして==
実際には、プリミティブ型の値を調べ、オブジェクトの場合は参照をチェックします。
==演算子は常に参照が比較されます。しかしの場合
equals()メソッド
オーバーライドされたメソッドで与えられた実装の基本でオブジェクトを比較するよりも、オーバーライドされた等しいメソッドであるかどうかは、実装に依存します。
class A
{
int id;
String str;
public A(int id,String str)
{
this.id=id;
this.str=str;
}
public static void main(String arg[])
{
A obj=new A(101,"sam");
A obj1=new A(101,"sam");
obj.equals(obj1)//fasle
obj==obj1 // fasle
}
}
上記のコードでは、objオブジェクトとobj1オブジェクトの両方に同じデータが含まれていますが、参照は同じではないため、equalsはfalseを返し、==も返します。しかし、equalsメソッドをオーバーライドした場合
class A
{
int id;
String str;
public A(int id,String str)
{
this.id=id;
this.str=str;
}
public boolean equals(Object obj)
{
A a1=(A)obj;
return this.id==a1.id;
}
public static void main(String arg[])
{
A obj=new A(101,"sam");
A obj1=new A(101,"sam");
obj.equals(obj1)//true
obj==obj1 // fasle
}
}
私たちがオーバーライドしたのと同じ場合にのみtrueとfalseが返されることを確認してください
メソッドに等しい。
オブジェクトのcontent(id)の基本でオブジェクトを比較します
しかし==
それでもオブジェクトの参照を比較します。
プリミティブ型のラッパーオブジェクト(つまり、Int、Long、Double)の場合、2つの値が等しい場合、==はtrueを返すことを追加する価値があるかもしれません。
Long a = 10L;
Long b = 10L;
if (a == b) {
System.out.println("Wrapped primitives behave like values");
}
対照的に、上記の2つのLongを2つの別々のArrayListsに入れると、equalsはそれらを同じものと見なしますが、==はそうではありません。
ArrayList<Long> c = new ArrayList<>();
ArrayList<Long> d = new ArrayList<>();
c.add(a);
d.add(b);
if (c == d) System.out.println("No way!");
if (c.equals(d)) System.out.println("Yes, this is true.");
==
多くのオブジェクトタイプで使用できますがObject.equals
、任意のタイプ、特に文字列とGoogleマップマーカーに使用できます。
Javaは演算子のオーバーロードをサポートしていないため==
、すべてのオブジェクトに対して同じように動作しますが、equals()
メソッドであり、Javaでオーバーライドでき、オブジェクトを比較するロジックはビジネスルールに基づいて変更できます。
==
Javaでのとequalsの主な違いは、"=="
プリミティブを比較するために使用されるのに対しequals()
、オブジェクトの同等性をチェックするためにメソッドが推奨されることです。
文字列の比較は、==
とequals()
メソッドの両方を使用する一般的なシナリオです。java.lang.Stringクラスのオーバーライドはメソッドと等しいため、2つのStringオブジェクトに同じコンテンツが含まれている==
場合はtrueを返しますが、2つの参照が同じオブジェクトを指している場合にのみtrueを返します。
これは、Javaで2つの文字列を比較して、いくつかの疑問を解消するメソッド==
とメソッドを使用して同等であるかどうかを比較する例です。equals()
public class TEstT{
public static void main(String[] args) {
String text1 = new String("apple");
String text2 = new String("apple");
//since two strings are different object result should be false
boolean result = text1 == text2;
System.out.println("Comparing two strings with == operator: " + result);
//since strings contains same content , equals() should return true
result = text1.equals(text2);
System.out.println("Comparing two Strings with same content using equals method: " + result);
text2 = text1;
//since both text2 and text1d reference variable are pointing to same object
//"==" should return true
result = (text1 == text2);
System.out.println("Comparing two reference pointing to same String with == operator: " + result);
}
}
public class StringPool {
public static void main(String[] args) {
String s1 = "Cat";// will create reference in string pool of heap memory
String s2 = "Cat";
String s3 = new String("Cat");//will create a object in heap memory
// Using == will give us true because same reference in string pool
if (s1 == s2) {
System.out.println("true");
} else {
System.out.println("false");
}
// Using == with reference and Object will give us False
if (s1 == s3) {
System.out.println("true");
} else {
System.out.println("false");
}
// Using .equals method which refers to value
if (s1.equals(s3)) {
System.out.println("true");
} else {
System.out.println("False");
}
}
}
----出力-----truefalse true
文字列プール(別名インターン)と整数プールは==
違いをさらに曖昧にし、場合によっては代わりにオブジェクトに使用できるようにすることができます.equals
これにより、複雑さが増しますが、パフォーマンス(?)が向上します。
例えば:
assert "ab" == "a" + "b";
Integer i = 1;
Integer j = i;
assert i == j;
複雑さのトレードオフ:次のことがあなたを驚かせるかもしれません:
assert new String("a") != new String("a");
Integer i = 128;
Integer j = 128;
assert i != j;
このようなマイクロ最適化を避け、常に.equals
オブジェクトと==
プリミティブに使用することをお勧めします。
assert (new String("a")).equals(new String("a"));
Integer i = 128;
Integer j = 128;
assert i.equals(j);
要するに、答えは「はい」です。
Javaでは、==
オペレーターは2つのオブジェクトを比較して、それらが同じメモリー位置を指しているかどうかを確認します。一方、.equals()
メソッドは実際に2つのオブジェクトを比較して、それらが同じオブジェクト値を持っているかどうかを確認します。
例1-
==メソッドと.equalsメソッドはどちらも、参照比較のためだけにあります。これは、両方のオブジェクトが同じオブジェクトを参照しているかどうかを意味します。
public class HelloWorld{
public static void main(String []args){
Object ob1 = new Object();
Object ob2 = ob1;
System.out.println(ob1 == ob2); // true
System.out.println(ob1.equals(ob2)); // true
}
}
例2-
ただし、equalsメソッドを使用してオブジェクトのコンテンツを比較する場合、クラスはオブジェクトのクラスequals()メソッドをオーバーライドし、コンテンツ比較の実装を提供する必要があります。ここで、Stringクラスは、コンテンツ比較のためにequalsメソッドをオーバーライドしています。すべてのラッパークラスは、コンテンツ比較のためにequalsメソッドをオーバーライドしています。
public class HelloWorld{
public static void main(String []args){
String ob1 = new String("Hi");
String ob2 = new String("Hi");
System.out.println(ob1 == ob2); // false (Both references are referring two different objects)
System.out.println(ob1.equals(ob2)); // true
}
}
例3-
Stringの場合、もう1つのユースケースがあります。ここで、文字列を文字列参照に割り当てると、文字列定数が文字列定数プール内に作成されます。同じ文字列を新しい文字列参照に割り当てると、新しい文字列定数は作成されず、既存の文字列定数を参照します。
public class HelloWorld{
public static void main(String []args){
String ob1 = "Hi";
String ob2 = "Hi";
System.out.println(ob1 == ob2); // true
System.out.println(ob1.equals(ob2)); // true
}
}
通常、hashCodeメソッドの一般的なコントラクトを維持するために、このメソッドがオーバーライドされるたびにhashCodeメソッドをオーバーライドする必要があることに注意してください。これは、等しいオブジェクトには等しいハッシュコードが必要であると述べています。
基本的に、==
2つのオブジェクトがヒープ上で同じ参照を持っているかどうかを比較するため、2つの参照が同じオブジェクトにリンクされていない限り、この比較はfalseになります。
equals()
Object
クラスから継承されたメソッドです。このメソッドは、デフォルトで、2つのオブジェクトが同じ参照を持っているかどうかを比較します。その意味は:
object1.equals(object2)
<=> object1 == object2
ただし、同じクラスの2つのオブジェクト間で同等性を確立する場合は、このメソッドをオーバーライドする必要があります。hashCode()
をオーバーライドした場合は、メソッドをオーバーライドすることも非常に重要ですequals()
。
hashCode()
平等を確立するときに実装するのは、Javaオブジェクトコントラクトの一部です。コレクションを使用していて、実装していない場合hashCode()
、奇妙な悪いことが起こる可能性があります。
HashMap<Cat, String> cats = new HashMap<>();
Cat cat = new Cat("molly");
cats.put(cat, "This is a cool cat");
System.out.println(cats.get(new Cat("molly"));
null
を実装していない場合は、前のコードを実行した後に出力されますhashCode()
。
それは同一性と同等性の違いです。
a == b
aとbが同一であることを意味します。つまり、これらはメモリ内のまったく同じオブジェクトのシンボルです。
a.equals( b )
これらは同等であり、ある意味で同じ値を持つオブジェクトのシンボルであることを意味します。ただし、これらのオブジェクトはメモリ内の異なる場所を占める場合があります。
同等性を使用すると、オブジェクトをどのように評価および比較するかという問題が発生することに注意してください。複雑なオブジェクトは、内容の一部が異なっていても、実際の目的では同等と見なされる場合があります。アイデンティティがあれば、そのような問題はありません。
簡単に==
言うと、両方のオブジェクトが同じメモリ位置を指しているかどうかをチェック.equals()
し、オブジェクトの値の比較を評価します。