ผู้สร้างคอมมอนส์ / lang นั้นยอดเยี่ยมและฉันใช้มันมาหลายปีโดยไม่มีค่าใช้จ่ายด้านประสิทธิภาพที่เห็นได้ชัดเจน (ทั้งที่มีและไม่มีไฮเบอร์เนต) แต่ในขณะที่ Alain เขียนวิธีของ Guava นั้นดีกว่า:
นี่คือตัวอย่างถั่ว:
public class Bean{
private String name;
private int length;
private List<Bean> children;
}
นี่คือสมการ () และ hashCode () ที่ใช้กับ Commons / Lang:
@Override
public int hashCode(){
return new HashCodeBuilder()
.append(name)
.append(length)
.append(children)
.toHashCode();
}
@Override
public boolean equals(final Object obj){
if(obj instanceof Bean){
final Bean other = (Bean) obj;
return new EqualsBuilder()
.append(name, other.name)
.append(length, other.length)
.append(children, other.children)
.isEquals();
} else{
return false;
}
}
และที่นี่ด้วย Java 7 หรือสูงกว่า (ได้แรงบันดาลใจจาก Guava):
@Override
public int hashCode(){
return Objects.hash(name, length, children);
}
@Override
public boolean equals(final Object obj){
if(obj instanceof Bean){
final Bean other = (Bean) obj;
return Objects.equals(name, other.name)
&& length == other.length // special handling for primitives
&& Objects.equals(children, other.children);
} else{
return false;
}
}
หมายเหตุ: รหัสนี้เดิมอ้างถึง Guava แต่เนื่องจากความคิดเห็นได้ชี้ให้เห็นว่าการทำงานนี้ได้รับการแนะนำใน JDK ดังนั้น Guava จึงไม่จำเป็นต้องใช้อีกต่อไป
อย่างที่คุณเห็นว่ารุ่น Guava / JDK นั้นสั้นกว่าและหลีกเลี่ยงวัตถุตัวช่วยที่ฟุ่มเฟือย ในกรณีที่เท่ากันมันยังช่วยให้การประเมินผลลัดวงจรถ้าการObject.equals()
โทรก่อนหน้านี้กลับเท็จ (เป็นธรรม: สามัญ / lang มีObjectUtils.equals(obj1, obj2)
วิธีการที่มีความหมายเหมือนกันซึ่งสามารถนำมาใช้แทนEqualsBuilder
การอนุญาตให้ลัดวงจรดังกล่าวข้างต้น)
ดังนั้น: ใช่ผู้สร้างคอมมอนส์ lang จะเป็นที่นิยมมากกว่าการสร้างด้วยตนเองequals()
และhashCode()
วิธีการ (หรืออสุรกายที่น่ากลัว Eclipse จะสร้างให้คุณ) แต่เวอร์ชัน Java 7+ / Guava ดีกว่ามาก
และหมายเหตุเกี่ยวกับไฮเบอร์เนต:
ระวังเกี่ยวกับการใช้งานคอลเล็กชันสันหลังยาวในการใช้งานเท่ากับ (), hashCode () และ toString () นั่นจะล้มเหลวอย่างน่าสังเวชถ้าคุณไม่มีเซสชันที่เปิดอยู่
หมายเหตุ (ประมาณเท่ากับ ()):
ก) ในทั้งสองรุ่นมีค่าเท่ากับ () ด้านบนคุณอาจต้องการใช้ทางลัดหนึ่งหรือทั้งสองอย่างด้วยเช่นกัน:
@Override
public boolean equals(final Object obj){
if(obj == this) return true; // test for reference equality
if(obj == null) return false; // test for null
// continue as above
b) ทั้งนี้ขึ้นอยู่กับการตีความสัญญาของคุณเท่ากับคุณอาจเปลี่ยนบรรทัด
if(obj instanceof Bean){
ถึง
// make sure you run a null check before this
if(obj.getClass() == getClass()){
หากคุณใช้รุ่นที่สองคุณอาจต้องการโทรsuper(equals())
ภายในequals()
วิธีการของคุณ ความคิดเห็นที่แตกต่างกันที่นี่หัวข้อจะกล่าวถึงในคำถามนี้:
วิธีที่ถูกต้องในการรวมซูเปอร์คลาสเข้ากับการใช้งาน Guava Objects.hashcode ()?
(แม้ว่าจะเป็นเรื่องhashCode()
เดียวกันก็ใช้กับequals()
)
หมายเหตุ (ได้แรงบันดาลใจจากความคิดเห็นจากkayahr )
Objects.hashCode(..)
(เช่นเดียวกับต้นแบบArrays.hashCode(...)
) อาจทำงานได้ไม่ดีหากคุณมีฟิลด์ดั้งเดิมจำนวนมาก ในกรณีเช่นนี้EqualsBuilder
อาจเป็นทางออกที่ดีกว่า
reflectionEquals
และreflectionHashcode
ฟังก์ชั่น; ประสิทธิภาพเป็นนักฆ่าที่สมบูรณ์