【永恒的瞬間】
          ?Give me hapy ?
          自動化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:
          1.在上述例子中,當有相同的firstname和lastname時,認為兩個對象的hashCode相同,從而equals()返回true.
          如果hashCode取決于該class的所有filed時需要使用反射機制來產生一個hashCode。
          public ? int ?hashCode(?)? {
          ????
          return ?HashCodeBuilder.reflectionHashCode( this
          );
          }
          和ToStringBuilder?與 HashCodeBuilder一樣EqualsBuilder 也是使用append()方法進行配置, EqualsBuilder的append()方法可以接受基本類型、對象、數組作為參數。EqualsBuilder強大的地方在于可以直接把數組作為參數傳入append()方法,EqualsBuilder會依次比較數組中的每個元素。
          2.如果兩個對象相等當且僅當每個屬性值都相等 這句話可以由以下代碼實現:
          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);

          }

          Discussion: CompareToBuilder.reflectionCompare()提供了兩個對象non-static和nontransient成員變量的方法。 reflectionCompare()方法不予理會static和transient變量,因此以下代碼中的averageAge和fullName變量是不會進入比較表達式的。
          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。
          ps:實現compareTo()的時候應保證和equals()規則相同,即當compareTo()返回是0的時候equals()應該返回true。

          1.1 ReflectionToStringBuilder

          本筆記是在閱讀Jakarta Commons Cookbook時所留下的。
          1.使用ReflectionToStringBuilder 或者ToStringBuilder 自動產生toString()的內容。
          ?? 使用舉例:假設有一個表征校長候選人信息的javabean-PoliticalCandidate。
          ??
          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?);
          ????}

          }

          該bean里面有個toString()方法,假設有以下操作:
          //?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@187aeca
          ??? [lastName=Jefferson,\firstName=Thomas,
          ???? dateOfBirth=Sat Apr 13 22:38:42 CST 1743,
          ???? moneyRaised=\293829292.930000007152557373046875,
          ???? state=\com.discursive.jccook.lang.builders.State@87816d
          ???????? [abbreviation=VA,name=Virginia]]

          ?

          org.apache.commons.lang.builder
            CompareToBuilder – 用于輔助實現Comparable.compareTo(Object)方法;
            
            EqualsBuilder – 用于輔助實現Object.equals()方法;
            
            HashCodeBuilder – 用于輔助實現Object.hashCode()方法;
            
            ToStringBuilder – 用于輔助實現Object.toString()方法;
            
            ReflectionToStringBuilder – 使用反射機制輔助實現Object.toString()方法;
            
            ToStringStyle – 輔助ToStringBuilder控制輸出格式;
            
            StandardToStringStyle – 輔助ToStringBuilder控制標準格式。
          posted on 2007-01-23 09:07 ???MengChuChen 閱讀(8076) 評論(0)  編輯  收藏 所屬分類: JavaBasic
          主站蜘蛛池模板: 化隆| 建湖县| 宁波市| 三门峡市| 延津县| 英山县| 乳山市| 乌拉特中旗| 永胜县| 略阳县| 江华| 五峰| 南投市| 延寿县| 长岛县| 兴化市| 汉沽区| 新沂市| 东城区| 吉林省| 富川| 苗栗市| 筠连县| 昭平县| 徐汇区| 拉孜县| 兖州市| 五台县| 顺昌县| 双城市| 南溪县| 乌鲁木齐市| 平阳县| 封开县| 阿巴嘎旗| 菏泽市| 宝清县| 锦州市| 江阴市| 东山县| 黄山市|