HashSet ใน Java
วันนี้เจอบั๊กแปลกๆ ที่ไม่คิดว่าจะเจอได้ในโค้ดงานที่ทำอยู่ สิ่งที่อาจเกิดขึ้นตามมาคือ memory leak ถ้าใช้ไม่ดี และมันก็เกิดกับ hash map ซะด้วย บั๊กที่ว่าคือ การเปลี่ยน hash code ของ object ใน key ของ hash map
สิ่งที่เกิดขึ้นเมื่อมีการเปลี่ยนแปลงก็คือ hash map จะไม่สามารถคืน object กลับมาได้หากนำ object นั้นไปใช้อ้างอิง ลองดูจาก code ด้านล่างละกัน
import java.util.HashSet; class A { String _data; A(String data) { _data = data; } public int hashCode() { int hash = 0; for(int i:_data.getBytes()) { hash += i; } return hash; } public boolean equals(Object obj) { if (obj instanceof A) return ((A)obj)._data.equals(_data); else return super.equals(obj); } } public class Test { public static void main(String... args) { HashSet sampleSet = new HashSet(); A a1 = new A("a1"); A a2 = new A("a2"); A a3 = new A("a3"); sampleSet.add(a1); sampleSet.add(a2); sampleSet.add(a3); a3._data = "a4"; System.out.println(sampleSet.contains(new A("a3"))); System.out.println(sampleSet.contains(new A("a4"))); System.out.println(sampleSet.contains(new A("a2"))); } }
ผลลัพธ์ที่ได้ก็คือ
llun@pluto:~/Desktop/Sample$ java Test false false true
จากตัวอย่างด้านบน ถ้าเราเพิ่ม A(”a4″) เข้าไปใน hash set จะยังเพิ่มได้โดยไม่ทับ object เก่า เนื่องจาก object อยู่ในช่อง array คนละช่องกันใน hash set แต่จะไม่สามารถเอาตัวที่ซ่อนอยู่ออกมาได้เลยยกเว้นใช้ iterator ไล่เอาที่ละตัวออกมา ดังนั้น object ที่จะใส่ใน hash ทั้งหลายแหล่ของจาวาจึงต้องระวังในการ override method hashCode() เพราะคงนึกภาพกันออกถ้า เอา object ใส่ไปใน hash แล้ว hash code เปลี่ยนหลังจากที่ใส่ไปทุกครั้ง จะเกิดอะไรขึ้น ถ้าจะทำอย่างนั้น hash set จะไม่ต่างจาก array ธรรมดาเลย
ปอลอ. วันนี้ประชุม แล้วนึกขึ้นได้ว่าต้องเตรียมเสนอ Apache Lucene กับ Apache POI แต่ยังไม่ได้ลองเล่นหรือหาข้อมูลเลย แย่แล้ว
ปอลอสอง. OpenSUSE 10.3 ออกเดือนหน้าแล้ว เดี๊ยว count down รออีกรอบดีกว่า ส่วน Ubuntu 7.10 คงสั่งเอาจากคลับหละ (สั่งพร้อมเสื้อ
)
- Java Generic
- Enum Factory
- Immutable pattern and string
- DataProvider ใน Tree component
- Regular expression กับภาษาไทย




Add Yours
YOU