String .Equals() vs ==

พอดีเมื่อวันพฤหัสก่อน เห็นน้องที่ทำงานใช้ Operator == ในการตรวจสอบว่า String เป็นอันเดียวกันไหม แต่ผมเห็นแล้วรู้สึกแปลกๆ มันควรใช้ Method Equals() มากกว่าครับ ใน Blog ตอนนี้ผมแสดงความแตกต่างของ .Equals() กับ == โดยผมยกตัวอย่างเฉพาะในภาษา Java และ C# ที่ผมใช้งานหลักอยู่ครับ

- JAVA

//Java Style
String nameA = "Chatri Ngambenchawong";
String nameB = "Chatri Ngambenchawong";
String nameC = new String("Chatri Ngambenchawong");

//=================================================
//Test 1
boolean resultEqualsMethodAB = nameA.equals(nameB);
//Result = True
//=================================================

//=================================================
//Test 2
boolean resultEqualsOperatorAB = nameA == nameB;
//Result = True
//=================================================

//=================================================
//Test 3
boolean resultEqualsMethodAC = nameA.equals(nameC);
//Result = True
//=================================================

//=================================================
//Test 4
boolean resultEqualsOperatorAC = nameA == nameC;
//Result = False
//=================================================

- C#

//C# Style
String nameA = "Chatri Ngambenchawong";
String nameB = "Chatri Ngambenchawong";
char[] values = {'C','h','a','t','r','i',' ','N','g','a','m'
,'b','e','n','c','h','a','w','o','n','g'};
String nameC = new String(values);
//=================================================
//Test 1
bool resultEqualsMethodAB = nameA.Equals(nameB);
//Result = True
//=================================================
//=================================================
//Test 2
bool resultEqualsOperatorAB = nameA == nameB;
//Result = True
//=================================================
//=================================================
//Test 3
bool resultEqualsMethodAC = nameA.Equals(nameC);
//Result = True
//=================================================
//=================================================
//Test 4
bool resultEqualsOperatorAC = nameA == nameC;
//Result = False
//=================================================

จาก Code ทั้ง 2 แบบ เราจะเห็นความแตกต่างกันของ String นะครับ (ตามตัวอย่างของ C# และ Java นะครับ)

  • Method Equals : มันตรวจสอบทั้ง Reference และ Value ครับ เจ้า Method Equals() เป็น polymorphic หลายคนอาจจะงงครับ ถ้าเป็นคำว่า Polymorphism อาจจะร้องอ๋อ
    • ในโลก OOP : Polymorphism ถ้าแปลตรงตัว เราอาจจะมองว่าเป็นไปได้หลายรูปแบบครับ ถ้ามองในแง่ของ Method การมีพฤติกรรมเหมือนกัน แต่เป็นไปได้หลากแบบ เช่น
      • คน มี Method เดิน(), วิ่ง()
      • แมว มี Method เดิน(), วิ่ง()
      • สุนัข มี Method เดิน(), วิ่ง()
    • Polymorphism มี Keyword อีก Overloading, Overriding ลองหาอ่านเพิ่มดูครับ
    • กลับมาที่ Equals ของเราดีกว่า เคสเดียวกันข้างต้น Equals ก็สามารถเขียนได้หลายรูปแบบครับ โดยเจ้า Class String ก็เตรียม Method Equals ไว้เหมือนกัน ถ้าไม่พอใจ เราสามารถ Override เขียนใหมได้ครับ และขอแถม Code Equals ของ Java แถมไว้นิดนึง
//Java 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;
}
  • Operator Equals (==) : ตรวจสอบ Reference อย่างเดียวครับ ตำแหน่งของหน่วยความจำใน Memory ถ้าเป็นพวกภาษา C ก็ Pointer นั้นแหละครับ
    • Question: อ้าวว แล้วทำไม จาก Code ตัวแปร nameA ถึง เท่ากับ nameB ได้หละ ?
    • Answer: เนื่องจากเป็นกลไกของภาษาครับ (ถ้าลงลึกเดี๋ยวงง) ถ้าเรากำหนดตัวแปร nameA กับตัวแปร nameB ขึ้นมา แต่ไม่ได้ New Object ใหม่ แบบ ตัวแปร nameC ระบบมันจัดการให้ตัวแปร nameA กับตัวแปร nameB ใช้ Memory ที่จุดเดียวกันครับ ผมขอตัด Code มาแปะนะครับ
/*
=========================================================
----------> JAVA
=========================================================
*/
String nameA = "Chatri Ngambenchawong";
String nameB = "Chatri Ngambenchawong";
String nameC = new String("Chatri Ngambenchawong");
/*
=========================================================
----------> C#
=========================================================
*/
String nameA = "Chatri Ngambenchawong";
String nameB = "Chatri Ngambenchawong";
char[] values = {'C','h','a','t','r','i',' ','N','g','a','m'
,'b','e','n','c','h','a','w','o','n','g'};
String nameC = new String(values);

สรุป ในการตรวจสอบว่า String เหมือนกัน ไม่ว่าเป็น Java หรือ C# ที่ผมยกตัวอย่างมา

ต้องใช้ Method Equals() ถึงเหมาะสมกว่านะครับ

เดี๋ยวเจอ Defect ที่คิดว่าเป็นความบกพร่องของตัวภาษา

แต่จริงๆแล้ว เรายังไม่เข้าใจมันมากกว่า


Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts sent to your email.