23 กันยายน, 2557

[Java] compare 2 array - เปรียบเทียบว่าอะเรย์2ตัวเท่ากันหรือไม่ด้วย .equals และ .deepEquals

การเทียบว่าค่าในตัวแปร 2 ตัวนี้เท่ากันหรือไม่เป็นสิ่งที่เขียนบ่อยมากเวลาเขียนโปรแกรม
ตัวอย่างเช่น
if( x == y ){
    print("equal");
}
ปกติถ้าคุณเป็นโปรแกรมเมอร์สาย C ก็คงจะเคยชินกับการใช้  ==  สำหรับการเช็กว่ามันเท่ากันมั้ย
แต่ถ้าตัวแปรตัวนั้นดันเป็น "object" ขึ้นมาล่ะ มันจะเกิดอะไรขึ้น?

การที่เราจับตัวแปรธรรมดามาเท่ากับกัน จะเรียกว่า "compare by value" คือ x เก็บค่าอะไรอยู่ y เก็บค่าอะไรอยู่ก็เอาค่าพวกนั้นแหละมาใช้ตรงๆ เลย

อย่างเคสนี้ สั่ง x == y ก็จะได้ประมาณ 10 เท่ากับ 10 มั้ย
แน่นอนว่าสำหรับเคสง่ายๆ แบบนี้มันจะได้  true  แน่นอนอยู่แล้ว

ปัญหาของเราจะเกิดขึ้นเมื่อตัวแปรที่จับมาเปรียบเทียบกันมันอยู่ในรูปของ Object เพราะว่าอะไรดูรูปข้างล่างนี้เลย


ไม่ใช่ value แต่เป็น reference

ตามปกติแล้ว ถ้าเรามีตัวแปรเราสามารถกำหนดค่าได้แบบนี้
int x = 10;
แต่ถ้าเป็น Object มันจะเป็นแบบนี้ (ยกตัวอย่างคลาส String ที่คนชอบคิดว่ามันเป็นตัวแปรธรรมดา แต่สังเกตดู String ขึ้นต้นด้วย S ตัวใหญ่ ไม่เหมือน int นะ)
String str = new String("nartra");
การสร้าง Object จะเริ่มจากคำสั่ง new สร้างตัวอ๊อบเจ็คขึ้นมาที่หนึ่ง ส่วนตัวแปรจะไม่ได้เก็บตัวอ๊อบเจ็คจริงๆ เอาไว้ แต่เก็บ pointer ชี้ไปที่ address ของอ๊อบเจ็คตัวนั้นแทน

เมื่อเป็นงั้น การจับอ๊อบเจ็ค 2 ตัวมา  ==  กันจะไม่ใช่การจับค่าที่ตัวแปรเก็บอยู่จริงๆ มาเปรียบเทียบกัน แต่เป็นค่า address ตั้งหาก ซึ่งผลที่ออกมาจะได้ทั้งเท่ากัน หรือไม่เท่าก็ได้

ถ้าอยากจะเอาค่ามันมาเปรียบเทียบกันจริงๆ ก็ต้องใช้เมททอด .equals เช็กเอา
สำหรับภาษา Java บ้าเรื่องอ๊อบเจ็คมาก Array มันก็มองเป็นอ๊อบเจ็คดังนั้นวิธีคือก็จะเหมือนกับอ๊อบเจ็คจัวอื่น

ซึ่งในกรณีของ Array จะเป็น

Arrays.equals

int[] arr1 = new int[]{10, 20, 30, 40, 50};
int[] arr2 = new int[]{10, 20, 30, 40, 50};

boolean equal = Arrays.equals(arr1, arr2);
ซึ่งมันจะใช้ได้กับ Array 1 มิติเท่านั้น ถ้าใช้กับ Array 2 มิติมันจะไม่ได้ผล ต้องเปลี่ยนไปใช้

Arrays.deepEquals

int[][] arr1 = new int[][]{{10, 20}, {30, 40}};
int[][] arr2 = new int[][]
{{10, 20}, {30, 40}};

boolean equal = Arrays.deepEquals(arr1, arr2);
การเปลี่ยนไปใช้ deepEquals แทนจะทำให้มันเช็กลงไปลึกกว่าชั้นมิติแรกได้

ไม่มีความคิดเห็น:

แสดงความคิดเห็น