apache 中的EqualsBuilder和HashCodeBuilder
自动化hashCode()和equals()
? 问题产生:当需要自动实现hashCode()和equals()方法
? 解决方法:使用EqualsBuilder和HashCodeBuilder?
? 使用举例:
?
?import??org.apache.commons.lang.builder.HashCodeBuilder;
?import??org.apache.commons.lang.builder.EqualsBuilder;
?public???class??PoliticalCandidate??{
?????//??Member?variables?-?omitted?for?brevity
?????//??Constructors?-?omitted?for?brevity
?????//??get/set?methods?-?omitted?for?brevity
?????//??A?hashCode?which?creates?a?hash?from?the?two?unique?identifiers?
?
??????public???int??hashCode(?)??{
?????????return???new??HashCodeBuilder(?17?,??37?)
???????????????????????.append(firstName)
???????????????????????.append(lastName).toHashCode(?);
????}?
?
?????//??An?equals?which?compares?two?unique?identifiers?
??????public???boolean??equals(Object?o)??{
?????????boolean??equals??=???false?;
?????????if??(?o??!=???null???&&?PoliticalCandidate.?class?.isAssignableFrom(o)?)??{
????????????PoliticalCandidate?pc??=??(PoliticalCandidate)?o;
????????????equals??=??(?new??EqualsBuilder(?)
???????????????????????.append(firstName,?ps.firstName)
???????????????????????.append(lastName,?ps.lastName)).isEquals(?);
????????}?
?????????return??equals;
????}?
?
}?
Discussion:
?public???int??hashCode(?)??{
?????return??HashCodeBuilder.reflectionHashCode(?this?);
}和ToStringBuilder?与?HashCodeBuilder一样EqualsBuilder?也是使用append()方法进行配置,?EqualsBuilder的append()方法可以接受基本类型、对象、数组作为参数。EqualsBuilder强大的地方在于可以直接把数组作为参数传入append()方法,EqualsBuilder会依次比较数组中的每个元素。
?public???boolean??equals(Object?o)??{
?????return??EqualsBuilder.reflectionEquals(?this?,?o);
}问题提出:需要快速实现compareTo()方法
解决方法:使用CompareToBuilder提供的compareTo()方法。同样的CompareToBuilder也使用了反射机制。以下代码提供了一个compareTo()方法,用于比较两个对象所有的非static和非transient成员变量。
?import??org.apache.commons.lang.builder.CompareToBuilder;
?//??Build?a?compareTo?function?from?reflection??
?public???int??compareTo(Object?o)??{
?????return??CompareToBuilder.reflectionCompare(?this?,?obj);
}
?public???class??PoliticalCandidate??{
?????//??Static?variable?
??????private???static??String?averageAge;
?????//??Member?variables??
??????private??String?firstName;
?????private??String?lastName;
?????private???transient??String?fullName;
?????//??Constructors
?????//??get/set?methods
?????//??Build?a?compareTo?function?from?reflection??
??????public???int??compareTo(Object?o)??{
?????????return??CompareToBuilder.reflectionCompare(?this?,?obj);
????}?
?
}比较对象成员变量的时候应该有一个比较的次序存在,上述代码中默认的应该是先比较lastName,然后是firstName。调用append()方法可以把要比较的变量加入比较表达式中,并且遵循后加入的先比较的次序。
?public???int??compareTo(Object?o)??{
?????int??compare??=???-?1?;??//??By?default?return?less-than?
??????if?(?o??!=???null???&&??PoliticalCandidate.?class?.isAssignableFrom(?o.getClass(?)?)?)??{
????????????PoliticalCandidate?pc??=??(PoliticalCandidate)?o;
????????????compare??=??(?new??CompareToBuilder(?)
??????????????????????????.append(firstName,?pc.firstName)
??????????????????????????.append(lastName,?pc.lastName)).toComparison(?);
????}?
?
?????return??compare;
}在比较的时候会先比较lastName,只有在lastName相同的情况下才会比较firstName。
public?class?PoliticalCandidate?{
????private?String?lastName;
????private?String?firstName;
????private?Date?dateOfBirth;
????private?BigDecimal?moneyRaised;
????private?State?homeState;
????//?get/set方法省略
????public?void?toString(?)?{
????????ReflectionToStringBuilder.toString(?this?);
????}
}
//?Create?a?State
State?va?=?new?State(?"VA",?"Virginia");
//?Create?a?Birth?Date
Calendar?calendar?=?new?GregorianCalendar(?);
calendar.set(?Calendar.YEAR,?1743?);
calendar.set(?Calendar.MONTH,?Calendar.APRIL?);
calendar.set(?Calendar.DAY_OF_MONTH,?13?);
Date?dob?=?calendar.getTime(?);
BigDecimal?moneyRaised?=?new?BigDecimal(?293829292.93?);????????
//?Create?a?Political?Candidate
PoliticalCandidate?candidate?=?
????new?PoliticalCandidate(?"Jefferson",?"Thomas",?dob,?moneyRaised,?va?);
?????
System.out.println(?candidate?);
假设State对象也是一个使用ReflectionToStringBuilder的javabean,上述程序一种可能的输出为com.discursive.jccook.lang.builders.PoliticalCandidate@187aecaorg.apache.commons.lang.builder
CompareToBuilder – 用于辅助实现Comparable.compareTo(Object)方法;
EqualsBuilder?– 用于辅助实现Object.equals()方法;
HashCodeBuilder – 用于辅助实现Object.hashCode()方法;
ToStringBuilder – 用于辅助实现Object.toString()方法;
ReflectionToStringBuilder – 使用反射机制辅助实现Object.toString()方法;
ToStringStyle – 辅助ToStringBuilder控制输出格式;
StandardToStringStyle – 辅助ToStringBuilder控制标准格式。