ฉันต้องการชี้แจงหากฉันเข้าใจสิ่งนี้อย่างถูกต้อง:
==
เป็นการเปรียบเทียบการอ้างอิงคือวัตถุทั้งคู่ชี้ไปที่ตำแหน่งหน่วยความจำเดียวกัน.equals()
ประเมินการเปรียบเทียบค่าในวัตถุ
.equals()
เป็นเทียบเท่ามีความหมาย
ฉันต้องการชี้แจงหากฉันเข้าใจสิ่งนี้อย่างถูกต้อง:
==
เป็นการเปรียบเทียบการอ้างอิงคือวัตถุทั้งคู่ชี้ไปที่ตำแหน่งหน่วยความจำเดียวกัน.equals()
ประเมินการเปรียบเทียบค่าในวัตถุ.equals()
เป็นเทียบเท่ามีความหมาย
คำตอบ:
โดยทั่วไปคำตอบสำหรับคำถามของคุณคือ "ใช่" แต่ ...
.equals(...)
จะเปรียบเทียบสิ่งที่เขียนเพื่อเปรียบเทียบไม่มากไม่น้อยไปequals(Object o)
เมธอดของคลาสพาเรนต์ที่ใกล้เคียงที่สุดซึ่งแทนที่เมธอดนี้Object#equals(Object o)
วิธีดังกล่าว สำหรับ Object API นี้จะเหมือนกับ==
; นั่นคือมันจะคืนค่าจริงถ้าหากทั้งสองตัวแปรอ้างถึงวัตถุเดียวกันหากการอ้างอิงของพวกเขาเป็นหนึ่งและเหมือนกัน ดังนั้นคุณจะได้รับการทดสอบความเสมอภาควัตถุและไม่เท่าเทียมกันทำงานhashCode
หากคุณแทนที่equals
เพื่อไม่ให้ "ผิดสัญญา" ตาม API ผลลัพธ์ที่ส่งคืนจากhashCode()
เมธอดสำหรับสองอ็อบเจ็กต์ต้องเหมือนกันถ้าequals
เมธอดของพวกเขาแสดงว่าเทียบเท่า การสนทนาไม่จำเป็นต้องเป็นเรื่องจริง==
ตรวจสอบการอ้างอิงหน่วยความจำแล้วทำไมฉันถึงได้รับพฤติกรรมแปลก ๆ นี้ใน [นี่] [1] [1]: docs.google.com/document/d/… ฉันคาดว่าผลลัพธ์จะเป็นจริง สามารถล้างความสับสนของฉัน
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
<br/> Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
( docs.oracle.com/javase/7/docs/api/java/lang/… )
ด้วยความเคารพคลาส String:
เท่ากับ () วิธีการเปรียบเทียบ "คุณค่า" ในกรณีสตริง (ในกอง) โดยไม่คำนึงถึงถ้าสองอ้างอิงวัตถุอ้างถึงเช่น String เดียวกันหรือไม่ ถ้ามีวัตถุสองชนิดที่อ้างอิงถึง String ชนิดอ้างอิงถึงอินสแตนซ์สตริงเดียวกันนั้นยอดเยี่ยม! หากการอ้างอิงวัตถุทั้งสองอ้างถึงสองอินสแตนซ์ของสตริงที่แตกต่างกัน .. มันไม่ได้สร้างความแตกต่าง มันคือ "คุณค่า" (นั่นคือ: เนื้อหาของอาร์เรย์อักขระ) ภายในแต่ละอินสแตนซ์ของสตริงที่จะถูกเปรียบเทียบ
บนมืออื่น ๆ ที่ "==" ผู้ประกอบการเปรียบเทียบค่าของสองอ้างอิงวัตถุเพื่อดูว่าพวกเขาอ้างถึงเดียวกันเช่น String หากค่าของการอ้างอิงวัตถุทั้งสอง "อ้างอิงถึง" อินสแตนซ์ของสตริงเดียวกันผลลัพธ์ของนิพจน์บูลีนจะเป็น "true" .. duh หากในทางกลับกันค่าของการอ้างอิงวัตถุทั้งสอง "อ้างอิงถึง" อินสแตนซ์ของสตริงที่แตกต่างกัน (แม้ว่าทั้งสองอินสแตนซ์ของสตริงมี "ค่า" เหมือนกันนั่นคือเนื้อหาของอาร์เรย์อักขระของแต่ละอินสแตนซ์ของสตริงจะเหมือนกัน) ผลลัพธ์ของนิพจน์บูลีนจะเป็น "false"
เช่นเดียวกับคำอธิบายใด ๆ ปล่อยให้มันจมลงมา
ฉันหวังว่าสิ่งนี้จะช่วยล้างสิ่งเล็กน้อย
String
s, ==
อ้างอิงเท่ากับเป็นอย่างดีใช่ แต่มันมักจะทำงาน (ในขณะที่ทั้งสองString
กำลังมีเนื้อหาเดียวกันจะมักจะเป็น==
กับแต่ละอื่น ๆ ) เนื่องจากวิธีการจับ Java String
s มันจะไม่เสมอไปและเป็นการฝึกฝนที่ไม่ดีอย่างแน่นอน แต่เป็นความผิดพลาดทั่วไปโดยเฉพาะอย่างยิ่งจากผู้ที่มาจากภาษาอื่น
String
สร้างจากสตริงตัวอักษรจะถูกเพิ่มลงในสิ่งที่เรียกว่าString constant pool
เช่นString s1 = "someString"; String s2 = "someString;"
ทั้งสองs1
และs2
จะแบ่งปันการอ้างอิงเดียวกัน s1 == s2
จะกลับมาจริง แต่ถ้าพวกเขาถูกสร้างขึ้นผ่านทางString constructor
เช่นString s1 = new String("someString"); String s2 = new String("someString");
พวกเขาจะไม่แบ่งปันการอ้างอิงเดียวกัน s1 == s2
จะกลับเท็จ
มีความแตกต่างเล็กน้อยขึ้นอยู่กับว่าคุณกำลังพูดถึง "ดั้งเดิม" หรือ "ประเภทวัตถุ"; เดียวกันสามารถพูดได้ถ้าคุณกำลังพูดถึงสมาชิก "คงที่" หรือ "ไม่คงที่"; คุณสามารถผสมทั้งหมดข้างต้น ...
นี่คือตัวอย่าง (คุณสามารถเรียกใช้):
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;
}
}
คุณสามารถเปรียบเทียบคำอธิบายสำหรับ "==" (Equality Operator) และ ".equals (... )" (เมธอดในคลาส java.lang.Object) ผ่านลิงก์เหล่านี้:
ความแตกต่างระหว่าง == และเท่ากับทำให้ฉันสับสนในบางครั้งจนกระทั่งฉันตัดสินใจที่จะมองใกล้ ๆ หลายคนบอกว่าสำหรับการเปรียบเทียบสตริงคุณควรใช้และไม่ได้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
โปรดเปรียบเทียบโปรแกรมด้านบนและลองคิดดู
ตกลง. ตอนนี้สิ่งนี้อาจช่วยได้ (โปรดอ่านสิ่งนี้: พิมพ์ที่อยู่ของวัตถุ - เป็นไปไม่ได้ แต่เรายังสามารถใช้งานได้)
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));
คุณสามารถลองคิดถึงผลลัพธ์ของสามบรรทัดสุดท้ายในรหัสด้านบน: สำหรับฉัน ideone พิมพ์ออกมา ( คุณสามารถตรวจสอบรหัสที่นี่ ):
false
true
true
false
mango mango
false
true
17225372
17225372
5433634
Oh! ตอนนี้คุณเห็นidentityHashCode (มะม่วง) เท่ากับ identityHashCode (mango2) แต่มันไม่เท่ากับ identityHashCode (mango3)
แม้ว่าตัวแปรสตริงทั้งหมด - mango, mango2 และ mango3 - มีค่าเดียวกันซึ่งก็คือ "mango" identityHashCode()
ยังคงไม่เหมือนเดิมสำหรับทุกคน
ทีนี้ลองยกเลิกการใส่เครื่องหมายบรรทัดนี้// mango2 = "mang";
แล้วเปิดใหม่อีกครั้งคราวนี้คุณจะเห็นทั้งสามอย่างidentityHashCode()
แตกต่าง อืมนั่นเป็นคำใบ้ที่มีประโยชน์
เรารู้ว่าถ้าhashcode(x)=N
และhashcode(y)=N
=>x is equal to y
ฉันไม่แน่ใจว่า java ทำงานอย่างไรภายใน แต่ฉันคิดว่านี่เป็นสิ่งที่เกิดขึ้นเมื่อฉันพูดว่า:
mango = "mango";
java สร้างสตริง"mango"
ที่ชี้ (อ้างอิง) โดยตัวแปรmango
บางอย่างเช่นนี้
mango ----> "mango"
ตอนนี้อยู่ในบรรทัดถัดไปเมื่อฉันพูดว่า:
mango2 = "mango";
จริง ๆ แล้วมันใช้ซ้ำสายเดียวกัน"mango"
ซึ่งมีลักษณะดังนี้
mango ----> "mango" <---- mango2
ทั้งมะม่วงและมะม่วง 2 ชี้ไปที่การอ้างอิงเดียวกันตอนนี้เมื่อฉันพูด
mango3 = new String("mango")
มันสร้างการอ้างอิงใหม่ (สตริง) สำหรับ "มะม่วง" โดยสมบูรณ์ ซึ่งมีลักษณะเช่นนี้
mango -----> "mango" <------ mango2
mango3 ------> "mango"
และที่ว่าทำไมเมื่อฉันใส่ออกค่าสำหรับมันใส่ออกmango == mango2
true
และเมื่อฉันใส่ค่าสำหรับmango3 == mango2
มันก็จะดับfalse
(แม้เมื่อค่าเหมือนกัน)
และเมื่อคุณไม่ใส่เครื่องหมายในบรรทัด// mango2 = "mang";
มันสร้างสตริง "mang" ซึ่งเปลี่ยนกราฟของเราดังนี้:
mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"
นี่คือเหตุผลที่ identityHashCode ไม่เหมือนกันสำหรับทุกคน
หวังว่านี่จะช่วยพวกคุณได้ ที่จริงแล้วฉันต้องการที่จะสร้างกรณีทดสอบที่ == ล้มเหลวและเท่ากับ () ผ่าน โปรดแสดงความคิดเห็นและแจ้งให้เราทราบหากฉันผิด
mango == mango2
เกิดขึ้นเพราะคุณไม่ได้สร้างmango2
เป็นวัตถุใหม่ String และแทนที่จะอ้างอิงเพียงโดยตรง"mango"
?
==ทดสอบผู้ประกอบการไม่ว่าจะเป็นตัวแปรทั้งสองมีการอ้างอิงเดียวกัน (หรือที่รู้จักตัวชี้ไปยังที่อยู่หน่วยความจำ)
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 ()จะทดสอบว่าตัวแปรสองตัวอ้างถึงวัตถุที่มีสถานะ (ค่าเดียวกัน)หรือไม่
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 () คุณสามารถเปรียบเทียบสถานะของวัตถุที่กล่าวอ้างกับสถานะส่งผ่านในวัตถุหรือคุณสามารถเรียก super.equals ()
==
เป็นผู้ประกอบการและequals()
เป็นวิธีการ
ผู้ประกอบการทั่วไปจะใช้สำหรับดั้งเดิมเปรียบเทียบชนิดและจึง==
ถูกนำมาใช้สำหรับการเปรียบเทียบที่อยู่หน่วยความจำและ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(...)
ต้องนำไปใช้กับชั้นเรียนที่คุณพยายามเปรียบเทียบ มิฉะนั้นจะมีจุดไม่มาก รุ่นของวิธีการสำหรับการเรียนวัตถุที่จะเป็นสิ่งเดียวกับการดำเนินการเปรียบเทียบ: วัตถุ # เท่าเทียมกัน
ครั้งเดียวที่คุณต้องการใช้ตัวดำเนินการเปรียบเทียบสำหรับวัตถุคือเมื่อคุณเปรียบเทียบ Enums นี่เป็นเพราะมีเพียงหนึ่งอินสแตนซ์ของค่า Enum ในแต่ละครั้ง ตัวอย่างเช่นกำหนด enum
enum FooEnum {A, B, C}
คุณจะไม่เคยมีมากกว่าหนึ่งตัวอย่างของA
ที่เวลาและเหมือนกันสำหรับและB
C
ซึ่งหมายความว่าคุณสามารถเขียนวิธีการเช่น:
public boolean compareFoos(FooEnum x, FooEnum y)
{
return (x == y);
}
และคุณจะไม่มีปัญหาใด ๆ
เมื่อคุณประเมินโค้ดมันชัดเจนมากว่า (==) เปรียบเทียบตามที่อยู่หน่วยความจำในขณะที่เท่ากับ (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
*/
นี่คือนิ้วหัวแม่มือทั่วไปของกฎสำหรับความแตกต่างระหว่างและrelational operator ==
the method .equals()
object1 == object2
เปรียบเทียบถ้าวัตถุอ้างอิงโดย object1 และ object2 อ้างถึง t เขาตั้งหน่วยความจำเดียวกันในกอง
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
การเปรียบเทียบสตริงนี้สามารถใช้เป็นพื้นฐานสำหรับการเปรียบเทียบวัตถุประเภทอื่น
ตัวอย่างเช่นถ้าฉันมีชั้นคนที่ฉันจำเป็นต้องกำหนดฐานเกณฑ์ที่ผมจะเปรียบเทียบคนสองคน สมมุติว่าคลาสบุคคลนี้มีตัวแปรอินสแตนซ์ของความสูงและน้ำหนัก
ดังนั้นการสร้างวัตถุบุคคลperson1 and person2
และสำหรับการเปรียบเทียบทั้งสองนี้โดยใช้.equals()
ฉันจำเป็นต้องแทนที่วิธีการที่เท่าเทียมกันของระดับบุคคลเพื่อกำหนดตามตัวแปรอินสแตนซ์ (heigh หรือน้ำหนัก) การเปรียบเทียบจะเป็น
== 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()
โดยปกติจะมี==
การทดสอบเนื่องจากนี่เป็นสิ่งแรกที่คุณต้องการทดสอบหากคุณต้องการทดสอบว่าวัตถุสองรายการเท่ากันหรือไม่
และ==
จริง ๆ แล้วดูที่ค่าสำหรับชนิดดั้งเดิมสำหรับวัตถุนั้นตรวจสอบการอ้างอิง
== โอเปอเรเตอร์ที่อ้างอิงเสมอจะถูกเปรียบเทียบ แต่ในกรณีของ
เท่ากับ () วิธีการ
มันขึ้นอยู่กับการนำไปใช้หากเราถูกแทนที่ด้วยวิธีที่เท่าเทียมกันมากกว่าที่จะเปรียบเทียบวัตถุบนพื้นฐานของการใช้งานที่กำหนดในวิธีการแทนที่
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 มีข้อมูลเดียวกัน แต่การอ้างอิงไม่เหมือนกันดังนั้นเท่ากับ return false และ == ด้วย แต่ถ้าเราแทนที่เมธอดเท่ากับวิธีกว่า
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
}
}
รู้ว่ามันจะกลับมาจริงและเท็จสำหรับกรณีเดียวกันเท่านั้นที่เราแทนที่
เท่ากับวิธีการ
มันเปรียบเทียบวัตถุบนพื้นฐานของเนื้อหา (id) ของวัตถุ
แต่ ==
ยังคงเปรียบเทียบการอ้างอิงของวัตถุ
ความแตกต่างที่สำคัญระหว่าง == และเท่ากับ () คือ
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
==
สามารถใช้ได้กับวัตถุหลายประเภท แต่คุณสามารถใช้ได้Object.equals
กับทุกประเภทโดยเฉพาะอย่างยิ่ง Strings และ Google Map Markers
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");
}
}
}
---- เอาท์พุท ----- จริงเท็จจริง
มันอาจจะคุ้มที่จะเพิ่มว่าสำหรับวัตถุห่อหุ้มสำหรับประเภทดั้งเดิม - เช่น Int, Long, Double - == จะกลับมาจริงถ้าทั้งสองค่าเท่ากัน
Long a = 10L;
Long b = 10L;
if (a == b) {
System.out.println("Wrapped primitives behave like values");
}
ในการเปรียบเทียบการวาง Longs สองรายการด้านบนเป็น ArrayLists ที่แยกกันสองรายการเท่ากับเห็นว่าเหมือนกัน แต่ == ไม่
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.");
Long a = 128l; Long b = 128l; System.out.println(a == b);
The String pool (aka interning ) และInteger poolเบลอความแตกต่างเพิ่มเติมและอาจทำให้คุณสามารถใช้==
สำหรับวัตถุในบางกรณีแทน.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 ==
ผู้ประกอบการเปรียบเทียบวัตถุทั้งสองเพื่อดูว่าพวกเขาชี้ไปที่ตำแหน่งหน่วยความจำเดียวกัน; ในขณะที่.equals()
วิธีการเปรียบเทียบวัตถุทั้งสองจริง ๆ เพื่อดูว่าพวกเขามีค่าวัตถุเดียวกัน
โดยทั่วไปให้==
เปรียบเทียบว่าวัตถุสองชิ้นมีการอ้างอิงเดียวกันกับฮีปดังนั้นหากการอ้างอิงสองรายการเชื่อมโยงกับวัตถุเดียวกันการเปรียบเทียบนี้จะเป็นเท็จ
equals()
เป็นวิธีการสืบทอดจากObject
ชั้นเรียน วิธีการนี้โดยค่าเริ่มต้นจะเปรียบเทียบหากวัตถุสองรายการมีการอ้างอิงเดียวกัน มันหมายถึง:
object1.equals(object2)
<=> object1 == object2
อย่างไรก็ตามหากคุณต้องการสร้างความเท่าเทียมกันระหว่างสองวัตถุของคลาสเดียวกันคุณควรจะแทนที่วิธีนี้ ยังเป็นสิ่งสำคัญมากที่จะแทนที่วิธีhashCode()
หากคุณมี equals()
overriden
ใช้งานhashCode()
เมื่อสร้างความเท่าเทียมกันเป็นส่วนหนึ่งของสัญญา Java Object หากคุณกำลังทำงานกับคอลเล็กชันและคุณยังไม่ได้ใช้งาน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()
จะถูกพิมพ์หลังจากรันรหัสก่อนหน้านี้ถ้าคุณยังไม่ได้ดำเนินการ
เนื่องจาก Java ไม่รองรับการโอเวอร์โหลดของผู้ให้บริการ == มีพฤติกรรมเหมือนกันสำหรับทุกวัตถุ แต่ equals () เป็นวิธีการซึ่งสามารถแทนที่ได้ใน Java และตรรกะเพื่อเปรียบเทียบวัตถุที่สามารถเปลี่ยนแปลงได้ตามกฎทางธุรกิจ
ความแตกต่างที่สำคัญระหว่าง == และเท่ากับใน Java คือ "==" ใช้เพื่อเปรียบเทียบ primitives ในขณะที่แนะนำให้ใช้วิธี equals () เพื่อตรวจสอบความเท่าเทียมกันของวัตถุ
การเปรียบเทียบสตริงเป็นสถานการณ์ทั่วไปของการใช้ทั้งวิธี == และเท่ากับ ตั้งแต่ java.lang.String การแทนที่คลาสเท่ากับเมธอดมันจะคืนค่าจริงถ้าวัตถุ String สองตัวมีเนื้อหาเดียวกัน แต่ == จะคืนค่าจริงถ้าการอ้างอิงสองรายการชี้ไปที่วัตถุเดียวกัน
นี่คือตัวอย่างของการเปรียบเทียบสอง Strings ใน Java เพื่อความเท่าเทียมกันโดยใช้วิธีการ == และ 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);
}
}