Heis的Blog

          保持簡單,保持愚蠢
          隨筆 - 29, 文章 - 1, 評論 - 122, 引用 - 0
          數據加載中……

          Jakarta Commons Cookbook讀書筆記--Commons Collections(函子篇)

          Jakarta Commons Cookbook讀書筆記系列

          3 Commons Collections v3.0
          功能說明:增強java的泛型框架,引入函子的概念

          主要功能:增加了一些函子的接口以及一些實現。包括一些實現了Comparator的類,封裝了條件和判別式的Predicate接口,實現對象轉換的Transformer接口以及模擬閉包的接口Closure;另外還有對jdk泛型框架的擴展。

          概念介紹:
          函子(functor):執行操作或功能的部件。例如java.util.Comparator和java.util.Iterator。他們都用于隔離算法。


          此次文章篇幅較長,讀者可以選擇著重閱讀斜體和著色文字,代碼部分可以選擇閱讀。
           
          3.1 Comparator的擴展

          3.1.1 使用ReverseComparator實現反順序排列。

          排序前
          Book book
          |--List authors
                    |--[0]->Person person1
                                    |--String name->"LiLei"
                    |--[1]->Person person2
                                    |--String name->"Ark"
                    |--[2]->Person person3
                                    |--String name->"HanMeimei"

          import  org.apache.commons.collections.comparators.ReverseComparator;
                                    
          Comparator nameComparor
          =new org.apache.commons.beanutils.BeanComparator("name");
          Comparator reverseComparator
          =new ReverseComparator(nameComparor);
          Collections.sort(book.getAuthors(),reverseComparator);


          按name屬性反向排序后
          Book book
          |--List authors
                    |--[0]->Person person1
                                    |--String name->"LiLei"
                    |--[1]->Person person2
                                    |--String name->"HanMeimei"
                    |--[2]->Person person3
                                    |--String name->"Ark"
          通常情況下,如果只有一個Comparator。ReverseComparator顯得有些雞肋,因為可以通過Arrays.reverse()和Collections.reverse()將數組或者List反轉。但是如果有多個Comparator,它的意義就顯現出來了。

          3.1.2 ComparatorChain結合多個Comparator進行排序

          import org.apache.commons.collections.comparators.ComparatorChain;

          Comparator nameComparor
          =new org.apache.commons.beanutils.BeanComparator("name");
          Comparator ageComparator
          =new org.apache.commons.beanutils.BeanComparator("age");
          ComparatorChain comparatorChain
          =new ComparatorChain();
          comparatorChain.addComparator(nameComparor);
          comparatorChain.addComparator(ageComparator);
          Collections.sort(book.getAuthors(),comparatorChain);


          先加入的Comparator擁有較高優先級。上面例子中20歲的Auther會排在18歲的Ben前面,而相同的名字則年輕的會排在前面。

          3.1.3 使用NullComparator包裝Comparator,控制對null的排序

          import org.apache.commmons.collections.comparators.NullComparator;

          //第二個參數為false,則name屬性為null的值排在非null的前面;如果為true,則反之。如果不加第二個參數,則默認為true;
          Comparator nullComparator =new NullComparator(nameComparator,false);


          3.1.4 使用FixedOrderComparator執行固定順序的排序

           public class PokerCard{  
               
          private String value;  
             
               
          private String suit;  
             
               ...
           }

          import org.apache.commons.collections.comparators.FixedOrderComparator

          //52張撲克牌從小到大排序例子
          String[] suitOrder=new String{"Diamond","Club","Heart","Spade"};
          String[] valueOrder
          =new  String{"2","3","4","5","6","7","8","9","10","J","Q","K","A"}

          Comparator suitComparator
          =new FixedOrderComparator(suitOrder);
          suitComparator
          =new BeanComparator("suit",suitComparator);
          Comparator valueComparator
          =new FixedOrderComparator(valueOrder);
          valueComparator
          =new BeanComparator("value",valueComparator);

          Comparator comparatorChain
          =new ComparatorChain();
          comparatorChain.add(suitComparator);
          comparatorChain.add(valueComparator);
          Collections.sort(pokerCardList,comparatorChain);

          3.2 使用Predicates封裝條件或者判別式
          以下所有的類都繼承org.apache.commons.collections.Predicate接口,而且該接口只有一個方法evaluate(Object)

          package org.apache.commons.collections;

          public interface Predicate {
              
          public boolean evaluate(Object object);
          }


          EqualsPredicate 相當于調用Equals對比
          IdentityPredicate 相當于==操作符
          NotPredicate 裝飾給定的Predicate并返回相反的值
          InstanceOfPredicate 相當于instanceof
          NullPredicate 當對象為null時返回true
          NullIsTruePredicate 裝飾給定的Predicate,如果對象為null則返回true,否則返回給定Predicate的判定值
          NotNullPredicate 當對象不為null時返回true
          NullIsFalsePredicate 裝飾給定的Predicate,如果對象為null則返回false,否則返回給定Predicate的判定值
          TruePredicate  總是返回true
          FalsePredicate 總是返回false
          UniquePredicate 首次evaluate判定對象總是返回true。其內部維護一個HashSet,每次調用evaluate(obj),將會調用HashSet的add方法。該類常用于Collections過濾重復的對象。

          import org.apache.commons.collections.Predicate;

          Predicate isHeis
          =new EqualsPredicate("Heis");
          Predicate notHeis
          =new NotPredicate(isHeis);
          Predicate nullIsTruePredicate
          =new NullIsTruePredicate(isHeis);
          Predicate instanceOfPredicate 
          =new InstanceOfPredicate(String.class);

          isHeis.evaluate(
          "Heis");->true
          notHeis.evaluate(
          "His");->true
          nullIsTruePredicate.evaluate(
          null);->true
          nullIsTruePredicate.evaluate(
          "Heis");->true
          instanceOfPredicate.evaluate(
          "Heis");->true

          3.2.1 復合Predicate實現復雜的條件邏輯
          AndPredicate and關系
          OrPredicate or關系
          AllPredicate 條件之間為and關系
          OnePredicate 當只有一個條件為true時,返回true
          AnyPredicate 條件之間為or關系

          Predicate isHeis
          =new EqualsPredicate("Heis");
          Predicate isNotNull
          =NotNullPredicate.INSTANCE;
          Predicate isMale
          =new EqualsPredicate("male");

          Predicate andPredicate
          =new AndPredicate(isHeis,isNotNull);
          Predicate orPredicate
          =new OrPredicate(isHeis,isNotNull);
          Predicate[] predicates
          =new Predicate[]{isHeis,isNotNull,isMale};
          Predicate allPredicate
          =new AllPredicate(predicates);
          Predicate onePredicate
          =new OnePredicate(predicates);


          3.3 利用Transformer實現對象轉換
          Transformer接口只有一個方法transform(),其設計的目的就是進行對象的轉換,接受一個對象并據此創建一個新對象。
          package org.apache.commons.collections;

          public interface Transformer {
              
          public Object transform(Object input);
          }


          import org.apache.commons.collections.Transformer;

          //大黃蜂變形器
          Transformer BumblebeeTrans=new Transform(){
              
          public Object transform(Object input){
                 
          if(input instanceof BumblebeeRobot){
                     
          return new BumblebeeCar(input);
                 }
          else{
                     
                 }
              }
          }

          //大黃蜂機器人模式轉換為汽車模式
          BumblebeeCar car=BumblebeeTrans.transform(BumblebeeRobot.getInstance());


          3.3.1 使用ChainedTransformer實現轉換鏈

          import org.apache.commons.collections.functors.ChainedTransformer;

          Transformer[] chainElements
          =new Transformer[]{transformer1,transformer2};
          Transformer chain
          =new ChainedTransformer(chainElements);

          Object transformedResult
          =chain.transform(input);

          3.3.2 結合Predicate和Transformer實現有條件的轉換

          import org.apache.commons.collections.functors.SwitchTransformer;

          Transformer defaultTransformer;

          Transformer[] tArray
          =new Transformer[]{t1,t2};
          Predicate[] pArray
          =new Predicate[]{p1,p2};

          Transformer st
          =new SwitchTransformer(tArray,pArray,defaultTransformer);
          //如果p1為true,則執行t1;如果p2為true,則執行t2;否則執行defaultTransformer
          Object tranformedResult=st.transform(input);


          3.4 模擬閉包的接口Closure
          package org.apache.commons.collections;

          public interface Closure {
              
          public void execute(Object input);
          }


          3.4.1 實現一個給商品價格打9折的Closure

          Closure discountClosure=new Closure(){
              
          public void execute(Object input){
                  Product p
          =(Product)input;
                  p.setPrice(p.getPrice()
          *0.9);
              }
          }


          3.4.2 使用ChainedClosure鏈接多個Closure

          import org.apache.commons.collections.functors.ChainedClosure;

          //對商品打九折,打包好后送達客戶
          Closure cArray=new Closure[]{discountClosure,packageClosure,postClosure};
          Closure process
          =new ChainedClosure(cArray);
          process.execute(product);


          3.4.3 使用IfClosure模擬條件語句

          import org.apache.commons.collections.functors.IfClosure;

          Predicate isDiscountProduct
          =new Predicate(){
              
          public boolean evaluate(Object object){
                  Product p
          =(Product)input;
                  
          return p.isDiscountProduct();
              }
          }
          //如果是折扣商品則打折出售(執行discountClosure.execute()),否則原價出售(執行noDiscountClosure.execute())。
          Closure discountAction=new IfColsure(isDiscountProduct,discountClosure,noDiscountClosure);
          discountAction.execute(product);


          因為IfClosure構造函數接受Closure作為參數,所以IfClosure還可以嵌入其他IfClosure

          3.4.4 使用WhileClosure,ForClosure模擬循環語句

          //判斷是否庫存過多
          Predicate isSurplus=new Predicate(){
              
          public boolean evaluate(Object object){
                  Product p
          =(Product)input;
                  
          return p.isSurplus();
              }
          }
          //如果庫存過多,繼續打折,直至庫存不在富余
          Closure getItCheap=new WhileClosure(isSurplus,discountClosure);
          getItCheap.execute(product);

          //對商品進行3次打折
          Closure getItCheap=new ForClosure(3,discountClosure);
          getItCheap.execute(product);

          Jakarta Commons Cookbook讀書筆記系列



          程序員的一生其實可短暫了,這電腦一開一關,一天過去了,嚎;電腦一開不關,那就成服務器了,嚎……

          posted on 2009-11-30 23:20 Heis 閱讀(2757) 評論(0)  編輯  收藏 所屬分類: Jakarta Commons Cookbook讀書筆記

          主站蜘蛛池模板: 乡城县| 乌兰浩特市| 兰考县| 青岛市| 阿巴嘎旗| 大姚县| 毕节市| 鄂温| 措美县| 马边| 丁青县| 札达县| 南汇区| 连云港市| 溧阳市| 太仆寺旗| 澄城县| 桓台县| 娱乐| 石城县| 凌源市| 新丰县| 珲春市| 时尚| 宁都县| 浠水县| 文安县| 桦甸市| 嘉禾县| 祥云县| 沁源县| 满洲里市| 望城县| 台中县| 紫云| 呼图壁县| 军事| 祁阳县| 滁州市| 房产| 资阳市|