ปริศนา Java 2 หลังจากเขียนภาคหนึ่งไว้ตั้งแต่สองสามเดือนก่อน คราวนี้ก็มาต่อภาคสองสักทีนะครับ สำหรับภาคนี้ คำถามก็ยังเหมือนเดิมครับ คือผลลัพธ์จากโปรแกรม Java นี้คืออะไร
เราลองมาวิเคราะห์โปรแกรมนี้กันดูนะครับ จะเห็นว่าเราประกาศอะเรย์ของ String ชื่อว่า URL_NAMES โดยสมาชิกแต่ละตัวของอะเรย์ก็คือ URL ของเว็บไซต์ต่าง ๆ แต่จะเห็นว่ามี //www.google.com ซ้ำกันอยู่ 2 ที่ จากนั้นที่เมท็อด main เราสร้างออบเจ็กของคลาส HashSet (ซึ่งจัดเป็นข้อมูลแบบเซ็ต) ใน for loop ก็มีการสร้างออบเจ็กต์ของ class URL โดยใช้สมาชิกแต่ละตัวจากอะเรย์ URI_NAMES และเก็บอ็อบเจกต์ของคลาส URL แต่ละตัวลงในเซ็ต พวกเราคงทราบนะครับว่าข้อมูลในเซ็ตจะไม่ซ้ำกัน แต่เรามีwww.google.com ซ้ำกันอยู่ 2 ตัวดังนั้น ดังนั้นข้อมูลในเซ็ตก็ควรจะมี 5 ตัว เมื่อเราสั่งพิมพ์ขนาดของเซ็ตออกมาในบรรทัดสุดท้าย ผลลัพธ์ก็ควรจะเป็น 5 ใช่ไหมครับ คำตอบก็ควรจะเป็นข้อ B แต่ไม่ใช่ครับ คำตอบคือข้อ D. ประหลาดใจไหมครับ คือถ้าคุณต่ออินเทอร์เน็ตอยู่ผลลัพธ์จะเป็นข้อ A. คือ 4 แต่ถ้าไม่ผลลัพธ์จะเป็น 5 ทำไมจึงเป็นเช่นนั้น เรามาดูกันครับ ความลับอยู่ที่เมท็อด equals ของคลาส URL ครับ วิธีการเปรียบเทียบว่า URL จะเท่ากันหรือไม่ดูดังนี้ครับ กล่าวคือถ้าเราต่ออินเทอร์เน็ตอยู่ มันจะแปล URL ไปเป็นหมายเลข IP ถ้าหมายเลข IP เท่ากันก็ถือว่าเป็น URL ตัวเดียวกัน แต่ถ้าเราไม่ต่ออินเทอร์เน็ต มันก็จะเอาค่าสตริงของ URL มาเปรียบเทียบ โดยไม่คำนึงถึงตัวอักษรตัวเล็กหรือตัวใหญ่ มาดูกรณีต่ออินเทอร์เน็ตอยู่ จะพบว่าในสตริงมี //www.google.com สองครั้ง ซึ่งก็ต้องได้ หมายเลข IP เดียวกันแน่นอน คราวนี้มาพิจารณาดู URL สองตัวนี้ครับ //www.ajsarun.blogspot.com กับ //ajsarun.blogspot.com สองตัวนี้จะให้ผลลัพธ์เป็นหมายเลข IP เดียวกัน นั่นก็หมายความว่าจะมีหมายเลข IP ที่ไม่ซ้ำกันอยู่ทั้งหมด 4 ตัวเท่านั้น ดังนั้นผลลัพธ์จึงเป็น 4 สำหรับกรณีที่ไม่ต่ออินเทอร์เน็ต มันก็จะเปรียบเทียบค่าสตริง URL ว่ามี //www.google.com อยู่ 2 ตัว ซึ่งซ้ำกัน ที่เหลือไม่ซ้ำดังนั้นผลลัพธ์จึงเป็น 5 เป็นยังไงครับรู้สึกอยากด่าหรืออยากเลิกใช้ Java ไปเลยไหมครับ คราวนี้ทำไมจึงเป็นเช่นนี้ พิธีกรเขาให้เหตุผลว่าในสมัยก่อนที่มีการสร้างคลาสนี้ยังไม่มีแนวคิดของการที่มีชื่อ URL ที่ต่างกัน แต่อ้างถึงหมายเลข IP เดียวกัน วิธีการแก้ไขถ้าต้องการให้ได้ผลลัพธ์ที่เหมือนเดิมเสมอไม่ว่าจะต่ออินเทอร์เน็ตหรือไม่ ให้ใช้คลาสที่ชื่อ URI แทนครับ ดังนั้นโปรแกรมในตอนต้นจะต้องเปลี่ยนเป็นดังนี้ครับ
ซึ่งคลาส URI นี้จะพิจารณาโดยใช้สตริงเท่านั้น คือไม่มีการไปแปลงเป็นหมายเลข IP ใด ๆ ดังนั้นผลลัพธ์จะเป็น 5 เสมอ แต่ก็ยังเป็นการเปรียบเทียบแบบไม่สนใจตัวอักษรตัวเล็กหรือตัวใหญ่เช่นเดิมนะครับคือ //www.google.com กับ //www.GOOGLE.COM ก็ถือว่าเท่ากัน สิ่งที่พิธีกรเขาสรุปจากปริศนานี้ก็คือ เขาบอกว่าเราไม่ควรใช้ URL กับ class SET หรือ class MAP เพราะว่ามันออกแบบมาไม่ดี ให้ใช้ URI แทน ซึ่งตรงนี้ผมว่าถ้าใครไม่ได้เขียนโปรแกรมที่เกี่ยวข้องกับเรื่องพวกนี้ก็อาจดูจะไกลตัวไปนะครับ แต่สิ่งที่เขาเน้นและผมก็คิดว่าสำคัญก็คือ เวลาเราเขียนโปรแกรม Java เมท็อดตัวหนึ่งที่เรามักจะ override ก็คือเมท็อด equals ก็ขอให้คิดไว้เสมอนะครับว่า เมท็อด equals นี้ไม่ควรจะให้ผลลัพธ์ที่เปลี่ยนไปตามสภาพแวดล้อมของการทำงาน ???
ต่อ internet อยู่ run ได้ 5 ข้อนี้ key มันอยู่ที่คุณสมบัติของ Set จ้า Set -> เก็บข้อมูลไม่ซ้ำกัน www.google.com = //www.google.com เลยได้ 5 โดย: DreamGlider วันที่: 2 สิงหาคม 2556 เวลา:2:27:49 น.
|
บทความทั้งหมด |
ไม่ค่อยได้ใช้ Class URI จึงไม่ทราบเลยว่า มีการไปตรวจสอบ equals ที่เป็น ip จริงๆด้วย
ผมใช้การ overide equals บ่อยสำหรับ obj ที่สร้างเอง
คงต้องระวัง ไม่ให้เปลี่ยนไปตามสภาพ เช่น ต่อเน็ท หรือ ไม่ต่อ ครับ
ขอบคุณกับความรู้ดีๆครับผม