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

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

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

    隨筆-14  評(píng)論-25  文章-1  trackbacks-0
    在一個(gè)項(xiàng)目里面有這么一個(gè)技術(shù)需求:
    1.集合中元素個(gè)數(shù),10M
    2.根據(jù)上限和下限從一個(gè)Set中過(guò)濾出滿足要求的元素集合.

    實(shí)際這個(gè)是個(gè)很典型的技術(shù)要求, 之前的項(xiàng)目也遇見(jiàn)過(guò),但是因?yàn)楫?dāng)時(shí)的類庫(kù)不多, 都是直接手寫實(shí)現(xiàn)的. 方式基本等同于第一個(gè)方式.

    在這個(gè)過(guò)程中, 我寫了四個(gè)方式, 基本記錄到下面.
    第一個(gè)方式:對(duì)Set進(jìn)行迭代器遍歷, 判斷每個(gè)元素是否都在上限和下限范圍中.如果滿足則添加到結(jié)果集合中, 最后返回結(jié)果集合.
                測(cè)試效果:集合大小100K, 運(yùn)算時(shí)間 3000ms+
    過(guò)濾部分的邏輯如下:
     1     void filerSet(Set<BigDecimal> targetSet, String lower, String higher) {
     2         BigDecimal bdLower = new BigDecimal(Double.parseDouble(lower));
     3         BigDecimal bdHigher = new BigDecimal(Double.parseDouble(higher));
     4 
     5         Set<BigDecimal> returnSet = new HashSet<BigDecimal>();
     6         for (BigDecimal object : targetSet) {
     7             if (isInRange(object, bdLower, bdHigher)) {
     8                 returnSet.add(object);
     9             }
    10         }
    11     }
    12 
    13     private boolean isInRange(BigDecimal object, BigDecimal bdLower,
    14             BigDecimal bdHigher) {
    15         return object.compareTo(bdLower) >= 0
    16                 && object.compareTo(bdHigher) <= 0;
    17     }
    第二個(gè)方式: 借助TreeSet, 原始集合進(jìn)行排序, 然后直接subset.
                測(cè)試效果: 集合大小10M, 運(yùn)算時(shí)間: 12000ms+(獲得TreeSet) , 200ms(獲得結(jié)果)
    過(guò)濾部分的邏輯如下(非常繁瑣):
      1     Set<BigDecimal> getSubSet(TreeSet<BigDecimal> targetSet, String lower,
      2             String higher) {
      3 
      4         BigDecimal bdLower = new BigDecimal(Double.parseDouble(lower));
      5         BigDecimal bdHigher = new BigDecimal(Double.parseDouble(higher));
      6 
      7         if ((bdHigher.compareTo(targetSet.first()) == -1)
      8                 || (bdLower.compareTo(targetSet.last()) == 1)) {
      9             return null;
     10         }
     11 
     12         boolean hasLower = targetSet.contains(bdLower);
     13         boolean hasHigher = targetSet.contains(bdHigher);
     14         if (hasLower) {
     15             if (hasHigher) {
     16                 System.out.println("get start:" + bdLower);
     17                 System.out.println("get end:" + bdHigher);
     18                 return targetSet.subSet(bdLower, true, bdHigher, true);
     19             } else {
     20                 BigDecimal newEnd = null;
     21                 System.out.println("get start:" + bdLower);
     22                 SortedSet<BigDecimal> returnSet = null;
     23                 if (bdHigher.compareTo(targetSet.last()) != -1) {
     24                     newEnd = targetSet.last();
     25                 } else {
     26                     SortedSet<BigDecimal> newTargetSet = targetSet
     27                             .tailSet(bdLower);
     28                     for (BigDecimal object : newTargetSet) {
     29                         if (object.compareTo(bdHigher) == 1) {
     30                             newEnd = object;
     31                             break;
     32                         } else if (object.compareTo(bdHigher) == 0) {
     33                             newEnd = object;
     34                             break;
     35                         }
     36                     }
     37                 }
     38                 returnSet = targetSet.subSet(bdLower, true, newEnd, true);
     39                 if (newEnd.compareTo(bdHigher) == 1) {
     40                     returnSet.remove(newEnd);
     41                 }
     42                 return returnSet;
     43             }
     44 
     45         } else {
     46             if (hasHigher) {
     47                 System.out.println("get end:" + bdHigher);
     48                 TreeSet<BigDecimal> newTargetSet = (TreeSet<BigDecimal>) targetSet
     49                         .headSet(bdHigher, true);
     50                 BigDecimal newStart = null;
     51                 SortedSet<BigDecimal> returnSet = null;
     52 
     53                 if (bdLower.compareTo(targetSet.first()) == -1) {
     54                     newStart = targetSet.first();
     55                 } else {
     56                     for (BigDecimal object : newTargetSet) {
     57                         if (object.compareTo(bdLower) != -1) {
     58                             newStart = object;
     59                             break;
     60                         }
     61                     }
     62                 }
     63                 returnSet = targetSet.subSet(newStart, true, bdHigher, true);
     64 
     65                 return returnSet;
     66             } else {
     67                 System.out.println("Not get start:" + bdLower);
     68                 System.out.println("Not get end:" + bdHigher);
     69                 BigDecimal newStart = null;
     70                 BigDecimal newEnd = null;
     71                 if (bdHigher.compareTo(targetSet.last()) != -1) {
     72                     newEnd = targetSet.last();
     73                 }
     74                 if (bdLower.compareTo(targetSet.first()) == -1) {
     75                     newStart = targetSet.first();
     76                 }
     77                 for (BigDecimal object : targetSet) {
     78                     if (newStart == null) {
     79                         if (object.compareTo(bdLower) != -1) {
     80                             newStart = object;
     81                             if (newEnd != null) {
     82                                 break;
     83                             }
     84                         }
     85                     }
     86 
     87                     if (newEnd == null) {
     88                         if (object.compareTo(bdHigher) != -1) {
     89                             newEnd = object;
     90                             if (newStart != null) {
     91                                 break;
     92                             }
     93                         }
     94                     }
     95                 }
     96 
     97                 if (newStart == null) {
     98                     if (newEnd == null) {
     99                         if ((bdHigher.compareTo(targetSet.first()) == -1)
    100                                 || (bdLower.compareTo(targetSet.last()) == 1)) {
    101                             return null;
    102                         }
    103                         return targetSet;
    104                     } else {
    105                         SortedSet<BigDecimal> newTargetSet = targetSet.headSet(
    106                                 newEnd, true);
    107                         if (newEnd.compareTo(bdHigher) == 1) {
    108                             newTargetSet.remove(newEnd);
    109                         }
    110                         return newTargetSet;
    111                     }
    112                 } else {
    113                     if (newEnd == null) {
    114                         SortedSet<BigDecimal> newTargetSet = targetSet.tailSet(
    115                                 newStart, true);
    116                         return newTargetSet;
    117                     } else {
    118                         SortedSet<BigDecimal> newTargetSet = targetSet.subSet(
    119                                 newStart, true, newEnd, true);
    120                         if (newEnd.compareTo(bdHigher) == 1) {
    121                             newTargetSet.remove(newEnd);
    122                         }
    123                         return newTargetSet;
    124                     }
    125                 }
    126             }
    127         }
    128     }
    第三種方式: 使用Apache Commons Collections, 直接對(duì)于原始Set進(jìn)行filter.
                測(cè)試效果:集合大小10M,過(guò)濾結(jié)果1M, 運(yùn)算時(shí)間: 1000ms+
    過(guò)濾部分的代碼如下:
     1 //過(guò)濾的主體邏輯
     2     void filterSet(Set<BigDecimal> targetSet, String lower, String higher) {
     3         final BigDecimal bdLower = new BigDecimal(Double.parseDouble(lower));
     4         final BigDecimal bdHigher = new BigDecimal(Double.parseDouble(higher));
     5 
     6         Predicate predicate = new Predicate() {
     7             public boolean evaluate(Object object) {
     8                 BigDecimal bDObject = (BigDecimal) object;
     9                 return bDObject.compareTo(bdLower) >= 0
    10                         && bDObject.compareTo(bdHigher) <= 0;
    11             }
    12         };
    13 
    14         CollectionUtils.filter(targetSet, predicate);
    15     }

    第四種方式:使用Guava(google Collections), 直接對(duì)于原始Set進(jìn)行Filter
                測(cè)試效果:集合大小10M,過(guò)濾結(jié)果1M, 運(yùn)算時(shí)間: 100ms-
    過(guò)濾部分的代碼如下:
     1 //guava filter
     2 
     3     Set<BigDecimal> filterSet(Set<BigDecimal> targetSet, String lower,
     4             String higher) {
     5         final BigDecimal bdLower = new BigDecimal(Double.parseDouble(lower));
     6         final BigDecimal bdHigher = new BigDecimal(Double.parseDouble(higher));
     7 
     8         Set<BigDecimal> filterCollection = Sets.filter(targetSet,
     9                 new Predicate<BigDecimal>() {
    10                     @Override
    11                     public boolean apply(BigDecimal input) {
    12                         BigDecimal bDObject = (BigDecimal) input;
    13                         return bDObject.compareTo(bdLower) >= 0
    14                                 && bDObject.compareTo(bdHigher) <= 0;
    15                     }
    16                 });
    17 
    18         return filterCollection;
    19     }


    四種方式對(duì)比如下:
    第一種方式:  僅依賴于JAVA原生類庫(kù) 遍歷時(shí)間最慢, 代碼量很小
    第二種方式:  僅依賴于JAVA原生類庫(kù) 遍歷時(shí)間比較慢(主要慢在生成有序Set), 代碼量最多
    第三種方式:  依賴于Apache Commons Collections, 遍歷時(shí)間比較快, 代碼量很少
    第四種方式:  依賴于Guava, 遍歷時(shí)間最快, 代碼量很少

    基于目前個(gè)人的技術(shù)水平和視野, 第四種方式可能是最佳選擇.

    記錄一下, 以后可能還會(huì)有更好的方案.




    posted on 2014-06-21 23:33 混沌中立 閱讀(7370) 評(píng)論(10)  編輯  收藏 所屬分類: about java & j2ee

    評(píng)論:
    # re: 一個(gè)簡(jiǎn)單的Java集合范圍過(guò)濾的多個(gè)方式對(duì)比 2014-06-22 18:07 | java論壇
    運(yùn)行效率好像沒(méi)多大差別哈

    http://www.itqx.net  回復(fù)  更多評(píng)論
      
    # re: 一個(gè)簡(jiǎn)單的Java集合范圍過(guò)濾的多個(gè)方式對(duì)比 2014-06-22 18:59 | 混沌中立
    第一個(gè)方式是10萬(wàn)數(shù)據(jù), 3000+ms,
    第二種是1千萬(wàn),12000ms
    第三種是1千萬(wàn), 3000ms
    第四種是1千萬(wàn), 100ms

    第一種和第四種比較的話, 可能有三個(gè)量級(jí)的區(qū)別, 區(qū)別巨大.

    @java論壇
      回復(fù)  更多評(píng)論
      
    # re: 一個(gè)簡(jiǎn)單的Java集合范圍過(guò)濾的多個(gè)方式對(duì)比 2014-06-23 00:07 | 亞歷山大
    guava并沒(méi)有立即執(zhí)行,而是緩執(zhí)行,遍歷下就知道了。無(wú)序的話,無(wú)論如何復(fù)雜度都是N。  回復(fù)  更多評(píng)論
      
    # re: 一個(gè)簡(jiǎn)單的Java集合范圍過(guò)濾的多個(gè)方式對(duì)比 2014-06-23 10:43 | 金利鎖業(yè)
    謝謝博主更新  回復(fù)  更多評(píng)論
      
    # re: 一個(gè)簡(jiǎn)單的Java集合范圍過(guò)濾的多個(gè)方式對(duì)比 2014-06-23 11:39 | java論壇
    @混沌中立

    謝謝
      回復(fù)  更多評(píng)論
      
    # re: 一個(gè)簡(jiǎn)單的Java集合范圍過(guò)濾的多個(gè)方式對(duì)比 2014-06-23 21:55 | 混沌中立
    確實(shí)有這種可能,
    但是 四種方式中size()的結(jié)果都是一致的.
    @亞歷山大
      回復(fù)  更多評(píng)論
      
    # re: 一個(gè)簡(jiǎn)單的Java集合范圍過(guò)濾的多個(gè)方式對(duì)比 2014-06-24 05:35 | 金利鎖業(yè)
    歡迎回訪啊  回復(fù)  更多評(píng)論
      
    # re: 一個(gè)簡(jiǎn)單的Java集合范圍過(guò)濾的多個(gè)方式對(duì)比 2014-07-08 10:03 | 博客寫什么
    高技術(shù)含量博客  回復(fù)  更多評(píng)論
      
    # re: 一個(gè)簡(jiǎn)單的Java集合范圍過(guò)濾的多個(gè)方式對(duì)比 2014-07-08 20:27 | 旺達(dá)鎖業(yè)
    謝謝你只關(guān)心  回復(fù)  更多評(píng)論
      
    # re: 一個(gè)簡(jiǎn)單的Java集合范圍過(guò)濾的多個(gè)方式對(duì)比 2014-07-19 14:56 | 個(gè)人品牌
    不大理解  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 麻豆va在线精品免费播放| 亚洲AV日韩AV永久无码久久| 成年女人午夜毛片免费视频| 亚洲国产精品人久久电影| 亚洲av无码潮喷在线观看| 亚洲熟女乱综合一区二区| 国产成人高清亚洲| 国产成人麻豆亚洲综合无码精品| 亚洲一区二区三区国产精品| 亚洲日韩中文在线精品第一| 亚洲毛片αv无线播放一区| 亚洲精品V欧洲精品V日韩精品| 亚洲av中文无码乱人伦在线咪咕 | 国产真人无码作爱免费视频| 成在线人视频免费视频| 野花香高清视频在线观看免费| 日本免费久久久久久久网站| 精品免费久久久久久久| 国产精品成人免费一区二区| 国产精品免费电影| 亚洲一级片免费看| 久久精品亚洲日本佐佐木明希| 91在线精品亚洲一区二区| 亚洲综合色在线观看亚洲| 久久精品亚洲乱码伦伦中文| 亚洲国产精品无码成人片久久| 亚洲免费视频网站| 久久精品国产亚洲AV久| 精品一区二区三区免费毛片| 在线免费观看伊人三级电影| 97在线视频免费播放| 成年女人看片免费视频播放器| 免费国产一级特黄久久| 亚洲乱码国产乱码精品精| 在线免费观看亚洲| 亚洲av无码专区在线观看亚| 国产vA免费精品高清在线观看| 日韩av无码久久精品免费| 妞干网手机免费视频| 亚洲综合色在线观看亚洲| 亚洲男人电影天堂|