ในบาง use case จำเป็นต้องมีการ overide equals กับ hashCode method
(ปกติใน object ที่เราไม่ได้ implement equals method
ความหมายของ equals ก็คือดูว่าเป็น instance เดียวกันหรือไม่
แต่ถ้าเราต้องการเปลี่ยนความหมายของ equals
ให้เป็นในลักษณะว่า property ทุกๆตัวเท่ากันหรือไม่แทน
ก็ต้อง override equals method ซึ่ง java object มี
constrain ว่าถ้าเรา overide equals method เมื่อไร
ก็ควรจะต้อง override hashCode method ด้วย
)
การเขียน method 2 อันนี้เราสามารถใช้
jakarta-commons-lang เข้ามาช่วยได้ โดยใช้ class
- HashCodeBuilder
- EqualsBuilder
public class Person {
String name;
int age;
boolean isSmoker;
...
public int hashCode() {
// you pick a hard-coded, randomly chosen, non-zero, odd number
// ideally different for each class
return new HashCodeBuilder(17, 37).
append(name).
append(age).
append(smoker).
toHashCode();
}
}
หรือจะใช้ reflection แทนก็ได้
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
ส่วนกรณี equals ก็เช่นเดียวกัน
public boolean equals(Object o) {ถ้าใช้ reflection
if ( !(o instanceof MyClass) ) {
return false;
}
MyClass rhs = (MyClass) o;
return new EqualsBuilder()
.appendSuper(super.equals(o))
.append(field1, rhs.field1)
.append(field2, rhs.field2)
.append(field3, rhs.field3)
.isEquals();
}
public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
ส่วนใครที่ใช้ Eclipse ถ้าอยากให้ชีวิตง่ายขึ้นกว่านี้อีก
ก็ต้องใช้ Commonclipse ซึ่งมี plugin ที่ช่วย generate
method ให้อีกที (ใช้ common lang builder เหมือนกัน)
Note: กรณีที่ใช้ hibernate มักจะมี
ข้อสงสัยว่าเราควรจะ override equals และ hashCode หรือไม่
ในกรณี use case ปกติ เราไม่จำเป็นต้อง override equals หรือ hashCode
เราจะ override ต่อเมื่อ
- it is a used as a composite primary key class
- instances of that class, loaded in different Hibernate Sessions, are in the same Set (or should be compared)
ส่วนรูปแบบการ implement ปกติจะใช้
public boolean equals(Object other) {
if ( !(other instanceof Client) ) return false;
Client castOther = (Client) other;
return new EqualsBuilder()
.append(this.getId(), castOther.getId())
.isEquals();
}
// Note: id is object id (surrogate identifier) of this object
public int hashCode() {
return new HashCodeBuilder()
.append(getId())
.toHashCode();
}
สถานะการณ์จะยุ่งยากขึ้นอีกถ้ามีการ compare proxy object กับ real object
อ่านเพิ่มเติมการถกเถึยงประเด็นเหล่านี้ได้ที่ this forum
No comments:
Post a Comment