[JAVA] Comparable vs Comparator

พอดีมีเรื่องให้ต้องเขียนโปรแกรมเพื่อช่วยการเรียงลำดับ แล้วมาสะดุดกับคำว่า Comparable และ Comparator ใน Java ว่ามันมีความแตกต่างกันอย่างไรและควรจะใช้งานอย่างไร

จากที่อ่านหลายๆกระทู้ใน stackoverflow และเว็บอื่นๆ พอสรุปคร่าวๆว่าที่แนะนำการใช้งานโดยอิงจาก natural order โดยเค้าจะแนะนำว่า

Comparable ใช้ในกรณีที่เป็น Natural Order

ส่วน Comparator ก็ใช้ในกรณีนอกเหนือจากนั้น

ส่วนวิธีการเปรียบเทียบ และผลลัพธ์ที่ส่งกลับจากการเปรียบเทียบนั้น เรียกว่าเกือบจะเหมือนๆกันเลย (ถ้าน้อยกว่าตัวที่เอามาเทียบ ส่งค่าลบ, เท่ากัน ส่งค่า 0, มากกว่าเป็นค่าบวก)

ทีนี้ก็เกิดคำถามว่า แล้ว Natural Order คืออะไร

หลังจากอ่านมาซักพัก ขอสรุปว่า Natural Order คืออะไรก็ได้ที่เป็นตัวบอกลำดับได้ โดยแนะนำว่าควรเป็นอะไรที่ไม่ว่าใครเห็นก็รู้ทันทีว่าเรียงลำดับอย่างไร ซึ่งจะมีประโยชน์เวลาคนอื่น เอาไปใช้งานต่อ เค้าจะรู้ได้ทันทีว่าพอสั่ง sort แล้วผลลัพธ์จะเป็นอย่างไร ยกตัวอย่างเช่น เราเขียน object salary ขึ้นมา natural order ของมันก็คือ ค่าเงินเดือนนั่นเอง ไม่ว่าใครก็จะเอาไปใช้ก็รู้ได้ทันทีว่าเวลาเรียงลำดับแล้วจะเป็นอย่างไร สิ่งของบางอย่างอาจจะเรียงลำดับตามตัวอักษร ตามชื่อ ซึ่งส่วนใหญ่แล้วสิ่งของเหล่านั้น จะมี property ไม่เยอะมาก หรือมี property เดียว

แต่ถ้า object ใดๆนั้นมีหลาย parameter โดยเป็น parameter หลักๆทั้งนั้น การตั้ง natural order ก็จะทำได้ลำบาก หรือไม่ควรทำจะดีกว่า เช่นเราเขียน object salaryMan ขึ้นมา โดยมี parameter ต่างๆ เช่น ชื่อ นามสกุล อายุ ตำแหน่ง อายุงาน เงินเดือน ฯลฯ ซึ่งเราไม่สามารถทำ natural order ให้ object นี้ได้ หรือถ้าทำได้ก็น่าจะเป็น ชื่อ ของ salaryMan

แต่การเปรียบเทียบ เรามีเรื่องต้องทำมากกว่า เช่น อยากเรียงลำดับตาม อายุ หรือ เรียงลำดับตาม เงินเดือน หรือ เรียงตามอายุก่อน ถ้าอายุเท่ากันให้เรียงตามเงินเดือน ฯลฯ

ซึ่งเงือนไขเหล่านี้จะมีได้ไม่จำกัด

เราจะพบว่าเราไม่ควร implement เงือนไขเหล่านี้ในตัว object salaryMan เพราะว่าเงื่อนไขอาจจะเปลี่ยนไปเปลี่ยนมาได้เสมอ ซึ่งถ้ามีการเอา object ตัวนี้ไปใช้ในงานอื่นแล้ว การแก้ไข Comparable จะทำให้งานอื่นๆนั้นเสียหายได้เลย

ในเคสนี้ เราควรสร้าง class ต่างหากขึ้นมาหนึ่งตัวโดย implement Comparator แทน เพื่อให้รับ object นี้เข้าไปทำการเปรียบเทียบ ซึ่งมันจะไม่กระทบต่อตัว object เลย

หากเราต้องการเปลี่ยนเงื่อนไข เราก็แก้ไขตัว comparator ได้เลย

หรือเราต้องการเปรียบเทียบด้วยเงื่อนไขอื่น เราก็สร้าง class สำหรับเปรียบเทียบตัวใหม่ขึ้นมาได้เลย ซึ่งจะทำให้ class object เหล่านั้นนำกลับมาใช้ใหม่ได้ง่ายขึ้นกว่ามาก

Facebooktwittergoogle_plusredditpinterestlinkedinmail