<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    邊城愚人

    如果我不在邊城,我一定是在前往邊城的路上。

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      31 隨筆 :: 0 文章 :: 96 評(píng)論 :: 0 Trackbacks

    過濾器集合

    ???????????????????????????????????? --一個(gè)實(shí)現(xiàn)過濾器集合的簡(jiǎn)易的通用機(jī)制

    ????????????????????????????????????????????????? By David Rappoport, JavaWorld.com, 10/18/04

    ??? 經(jīng)常地,你必須遍歷一個(gè)對(duì)象集合并基于一些條件(criteria)來過濾它們。JDK提供了有用的機(jī)制來排序集合,即Comparator接口。然而,JDK缺少過濾集合的機(jī)制。

    ??? 這篇文章描述了一個(gè)僅由一個(gè)類和一個(gè)接口組成的簡(jiǎn)單機(jī)制,它允許你快速和靈活地過濾集合。當(dāng)搜索一個(gè)集合時(shí),該機(jī)制提供了與SQL中的select語句相同的功能。它的隱含的概念是,在遍歷集合和過濾集合中的對(duì)象時(shí),達(dá)到職責(zé)的分離。
    ??? 這里提出的方法有下面的優(yōu)點(diǎn):
    ??? 1、一個(gè)核心的過濾器組件的復(fù)用產(chǎn)生更清晰的代碼。
    ??? 2、通用過濾組件的復(fù)用產(chǎn)生更免于錯(cuò)誤的代碼。
    ??? 3、從過濾邏輯中分離出迭代邏輯使你任意地增加和刪除過濾器而不影響到其他代碼。
    ??? 4、對(duì)于大集合和多個(gè)criteria能夠獲得性能提高。

    問題

    ??? 想象一個(gè)搜索接口(mask),用戶通過選擇眾多不同的條件(criteria)來搜索汽車。為了簡(jiǎn)單地完成這個(gè)任務(wù),開發(fā)者必須多次遍歷(iterate)集合。在每一次遍歷中,他必須對(duì)集合中的每一個(gè)對(duì)象執(zhí)行一定的邏輯來確定該對(duì)象是否滿足條件(criteria)。通常,這個(gè)過程的結(jié)果是很難閱讀和維護(hù)的凌亂的代碼。

    解決辦法

    ??? 我們定義了一個(gè)類CollectionFilter和一個(gè)接口FilterCriteria。FilterCriteria僅僅定義了一個(gè)方法:public boolean passes(Object o)。這個(gè)方法中,集合中的一個(gè)對(duì)象必須通過一定的測(cè)試。如果它通過測(cè)試,該方法返回true,否則返回false。CollectionFilter接收一些FilterCriteria作為輸入。然后你能調(diào)用public void filter(Collection)方法,該方法應(yīng)用了集合中所有的FilterCriteria,并刪除集合中沒有通過所有FilterCriteria的任何對(duì)象。
    CollectionFilter類也定義了public Collection filterCopy(Collection)方法,它完成和filter(Collection)方法相同的任務(wù),但對(duì)原始的過濾器做了復(fù)制。代碼如下(譯者添加):

    package?com.drap.filter;

    /**
    ?*?<p>Title:?FilterCriteria</p>
    ?*?<p>Description:?A?FilterCriteria?is?added?to?the?CollectionFilter?to?filter
    ?*?all?the?objects?in?the?collection.?</p>
    ?*?
    @author?David?Rappoport
    ?*?
    @version?1.0
    ?
    */

    public?interface?FilterCriteria?{

    ????
    /**
    ?????*?Implement?this?method?to?return?true,?if?a?given?object?in?the?collection
    ?????*?should?pass?this?filter.
    ?????*?Example:?Class?Car?has?an?attribute?color?(String).?You?only?want?Cars
    ?????*?whose?color?equals?"red".
    ?????*?1)?Write?the?FilterCriteria?implementation:
    ?????*?class?RedColorFilterCriteria?implements?FilterCriteria{
    ?????*?????public?boolean?passes(Object?o){
    ?????*?????????return?((Car)o).getColor().equals("red");
    ?????*?????}
    ?????*?}
    ?????*?2)?Then?add?this?FilterCriteria?to?a?CollectionFilter:
    ?????*?CollectionFilter?filter?=?new?CollectionFilter();
    ?????*?filter.addFilterCriteria(new?ColorFilterCriteria());
    ?????*?3)?Now?filter:
    ?????*?filter.filter(carCollection);
    ?????*?
    @param?o
    ?????*?
    @return
    ?????
    */
    ????
    public?boolean?passes(Object?o);
    }

    package?com.drap.filter;



    import?java.lang.reflect.*;

    import?java.util.*;


    /**

    ?*?<p>Title:?CollectionFilter</p>

    ?*?<p>Description:?</p>

    ?*?
    @author?David?Rappoport

    ?*?
    @version?1.0

    ?
    */

    public?class?CollectionFilter?implements?java.io.Serializable?{


    ???
    private?ArrayList?allFilterCriteria?=?new?ArrayList();

    ???
    /**

    ?????*?Adds?a?FilterCriteria?to?be?used?by?the?filter

    ?????*?
    @param?filterCriteria

    ?????
    */

    ????
    public?void?addFilterCriteria(FilterCriteria?filterCriteria){

    ????????allFilterCriteria.add(filterCriteria);

    ????}


    ????
    /**

    ?????*?Starts?the?filtering?process.?For?each?object?in?the?collection,

    ?????*?all?FilterCriteria?are?called.?Only?if?the?object?passess

    ?????*?all?FilterCriteria?it?remains?in?the?collection.?Otherwise,?it?is?removed.

    ?????*?
    @param?collection

    ?????
    */

    ????
    public?void?filter(Collection?collection){

    ???????
    if(collection?!=?null){

    ????????????Iterator?iter?
    =?collection.iterator();

    ????????????
    while(iter.hasNext()){

    ????????????????Object?o?
    =?iter.next();

    ????????????????
    if(!passesAllCriteria(o)){

    ????????????????????iter.remove();

    ????????????????}

    ????????????}

    ????????}

    ????}



    ????
    /**

    ?????*?This?method?does?the?same?as?the?filter?method.?However,?a?copy?of

    ?????*?the?original?collection?is?created?and?filtered.?The?original?collection

    ?????*?remains?unchanged?and?the?copy?is?returned.?Only?use?this?method

    ?????*?for?collection?classes?that?define?a?default?constructor

    ?????*?
    @param?inputCollection

    ?????*?
    @return?a?filtered?copy?of?the?input?collection

    ?????
    */

    ????
    public?Collection?filterCopy(Collection?inputCollection){

    ????????Collection?outputCollection?
    =?null;

    ????????
    if(inputCollection?!=?null){

    ??????????? outputCollection?
    =?(Collection)createObjectSameClass(inputCollection);

    ????????????outputCollection.addAll(inputCollection);

    ????????????Iterator?iter?
    =?outputCollection.iterator();

    ????????????
    while(iter.hasNext()){

    ????????????????Object?o?
    =?iter.next();

    ????????????????
    if(!passesAllCriteria(o)){

    ????????????????????iter.remove();

    ????????????????}
    ??????????? }

    ????????}

    ????????
    return?outputCollection;

    ????}

    ????
    /**

    ?????*?Makes?sure?the?specified?object?passes?all?FilterCriteria's?passes?method.

    ?????*?
    @param?o

    ?????*?
    @return

    ?????
    */

    ????
    private?boolean?passesAllCriteria(Object?o){

    ????????
    for(int?i?=?0;?i?<?allFilterCriteria.size();?i?++){

    ????????????FilterCriteria?filterCriteria?
    =?(FilterCriteria)allFilterCriteria.get(i);

    ????????????
    if(!filterCriteria.passes(o)){

    ????????????????
    return?false;
    ??????????? }

    ????????}

    ????????
    return?true;

    ????}


    ????
    /**

    ?????*?Call?the?no?arguments?constructor?of?the?object?passed

    ?????*?
    @param?object

    ?????*?
    @return

    ?????
    */

    ????
    public?Object?createObjectSameClass(Object?object){

    ??????? Class[]?NO_ARGS?
    =?new?Class[0];

    ????????Object?sameClassObject?
    =?null;

    ????????
    try{

    ????????????
    if(object?!=?null){

    ????????????????Constructor?constructor?
    =?object.getClass().getConstructor(NO_ARGS);

    ????????????????sameClassObject?
    =?constructor.newInstance(NO_ARGS);

    ????????????}

    ????????}
    catch(IllegalAccessException?e){

    ????????????
    //@todo?do?something

    ????????}
    catch(NoSuchMethodException?e){

    ????????????
    //@todo?do?something

    ????????}
    catch(InstantiationException?e){

    ????????????
    //@todo?do?something

    ????????}
    catch(Exception?e){

    ????????????
    //@todo?do?something

    ????????}

    ????????
    return?sameClassObject;

    ????}


    }


    ??? 就是這樣了!
    ??? 就像你可能已經(jīng)注意到了,這個(gè)解決方法使用了職責(zé)鏈設(shè)計(jì)模式的部分思想并應(yīng)用它們到集合中。
    ??? 下面的類圖說明了類和接口及它們之間的關(guān)系。
    jw-1018-filter.gif

    簡(jiǎn)單的例子

    ??? 讓我們看一個(gè)例子:類car有三個(gè)屬性:String color, double maxSpeed, boolean fourWheelDrive。
    你的應(yīng)用程序允許基于這些條件來搜索cars:用戶能輸入她喜歡的顏色,她也能提供她想要car擁有的最大速度,及car是否支持four-wheel驅(qū)動(dòng)。
    ??? 我們現(xiàn)在創(chuàng)建三個(gè)過濾器類來滿足用戶選擇的條件。
    ??? 1、FilterCriteria的實(shí)現(xiàn)如下:

    class?ColorFilterCriteria?implements?FilterCriteria{
    ????
    private?String?color;
    ????
    public?boolean?passes(Object?o){
    ????????
    return?((Car)o).getColor().equals(color);
    ????}
    }
    class?MaxSpeedFilterCriteria?implements?FilterCriteria{
    ????
    private?int?maxSpeed;
    ????
    public?boolean?passes(Object?o){
    ????????
    return?((Car)o).getMaxSpeed()?>=?maxSpeed;
    ????}
    }
    class?FourWheelDriveFilterCriteria?implements?FilterCriteria{
    ????
    private?boolean?fourWheelDriveRequired;
    ????
    private?boolean?fourWheelDriveAllowed;
    ????
    public?boolean?passes(Object?o){
    ????????
    return?fourWheelDriveRequired?((Car)o).isFourWheelDrive():fourWheelDriveAllowed?true:!
    ????((Car)o).isFourWheelDrive();
    ????}
    }

    ??? 2、添加這些FilterCriteria到CollectionFilter中。

    CollectionFilter?collectionFilter?=?new?CollectionFilter();
    filter.addFilterCriteria(
    new?ColorFilterCriteria(color));
    filter.addFilterCriteria(
    new?MaxSpeedFilterCriteria(maxSpeed));
    filter.addFilterCriteria(
    new?FourWheelDriveFilterCriteria(fourWheelDriveRequired,?fourWheelDriveAllowed));

    ??? 3、調(diào)用過濾方法:

    collectionFilter.filter(carCollection);

    技術(shù)的使用(Technicalities)

    ??? 正如你可能意識(shí)到的,和Comparator接口中的compare(Object o1, Object o2)方法相似,F(xiàn)ilterCriteria接口中的passes(Object o)方法接收任何類型的對(duì)象作為輸入?yún)?shù)。這意味著你必須將對(duì)象轉(zhuǎn)換成你想要工作的類型并確保你的集合中僅僅包含那種類型的對(duì)象。如果這個(gè)不是確定的,你能使用instanceof測(cè)試指定的對(duì)象是否為那種類型。(譯者注:根據(jù)需要,可以使用范型解決類型轉(zhuǎn)換問題,由于這篇文章實(shí)在是太早了,所以作者才有了這段內(nèi)容。)
    ??? 有時(shí)候,你可能不喜歡為每一個(gè)FilterCriteria定義一個(gè)單獨(dú)的類,這種情況下可以使用匿名的內(nèi)部類。
    為了使解決方法簡(jiǎn)單些,我對(duì)這個(gè)過濾器并沒有使用OR功能。換句話說,每次你增加一個(gè)FilterCriteria到你的CollectionFilter,可以當(dāng)作是SQL中的AND操作。然而,你也能容易的在一個(gè)FilterCriteria增加像OR的功能。例如:

    class?EitherOrColorFilterCriteria?implements?FilterCriteria{
    ????
    private?String?color1;
    ????
    private?String?color2;
    ????
    public?boolean?passes(Object?o){
    ????????
    return?((Car)o).getColor().equals(color1)?||?((Car)o).getColor().equals(color2);
    ????}
    }

    結(jié)論

    ??? 如你所看到的,基于多個(gè)條件來過濾集合是簡(jiǎn)單的。每一個(gè)FilterCriteria對(duì)象僅對(duì)它表示的單個(gè)的過濾邏輯負(fù)責(zé)。CollectionFilter然后聯(lián)合所有的過濾器來產(chǎn)生想要的結(jié)果。對(duì)于其它種類的集合處理的相似的解決方法也是可以想到的(除了刪除操作)。這個(gè)解決方法使用了職責(zé)鏈和迭代器模式:CollectionFilter在集合之上迭代,對(duì)于集合中的每一個(gè)對(duì)象,F(xiàn)ilterCriteria對(duì)象被當(dāng)作職責(zé)鏈,而每一個(gè)過濾器能決定其它的過濾器是否是需要的。

    作者Bio David Rappoport 已經(jīng)在IBM Global Services 和 Credit Suisse Application Development 工作了五年, 在那兒他開發(fā)J2EE領(lǐng)域的軟件。他是一個(gè)SUN認(rèn)證的Java 2 程序員,SUN認(rèn)證的Java 2開發(fā)者,SUN認(rèn)證的J2EE 架構(gòu)師,和SUN認(rèn)證的業(yè)務(wù)組件開發(fā)者。他和他的妻子幾兩個(gè)孩子生活在瑞士。

    注:該文為本人第一篇和技術(shù)相關(guān)的翻譯文章(論文就不算了)。由于本人水平有限,翻譯中難免有不對(duì)的地方,歡迎各位朋友指正。該文出處為http://www.javaworld.com/javaworld/jw-10-2004/jw-1018-filter.html,是一篇很早的文章(2004年),內(nèi)容上也算是比較簡(jiǎn)單的。
    posted on 2007-06-30 22:22 kafka0102 閱讀(1349) 評(píng)論(1)  編輯  收藏 所屬分類: Translation

    評(píng)論

    # re: [翻譯]過濾器集合 2007-07-01 19:56 soft4any
    不錯(cuò)。實(shí)際上這個(gè)類的設(shè)計(jì)思想在File中已經(jīng)存在了,遍歷子File的時(shí)候,jdk提供了FileFilter類  回復(fù)  更多評(píng)論
      


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲av片在线观看| 日韩欧美亚洲中文乱码| 亚洲91精品麻豆国产系列在线| 亚洲乱码一二三四五六区| 亚洲午夜无码久久| 国产午夜亚洲精品不卡免下载| a免费毛片在线播放| 一区二区在线免费观看| 成年男女男精品免费视频网站| 四虎影院永久免费观看| 精品亚洲综合在线第一区| 亚洲成人黄色在线观看| 国产成人亚洲精品播放器下载| 久久九九久精品国产免费直播| 97av免费视频| 四虎影视在线永久免费看黄| 亚洲婷婷五月综合狠狠爱| 亚洲国产精品久久久久秋霞影院| 亚洲国产精品无码第一区二区三区| 一级**爱片免费视频| 50岁老女人的毛片免费观看| 国产精品高清全国免费观看| 亚洲精品无码久久久久sm| 亚洲kkk4444在线观看| 色老头综合免费视频| 131美女爱做免费毛片| 国产在线观看免费视频播放器| 亚洲va无码va在线va天堂| 亚洲首页国产精品丝袜| 中文永久免费观看网站| 免费无码又黄又爽又刺激| 在线观看亚洲av每日更新| 亚洲狠狠成人综合网| 两个人看的www免费| 成人a视频片在线观看免费| 精品亚洲永久免费精品| 亚洲日韩精品无码AV海量| 人人揉揉香蕉大免费不卡| 日本午夜免费福利视频| 亚洲一区二区三区首页| 农村寡妇一级毛片免费看视频|