在一个项目里面有这么一个技术需求:
1.集合中元素个数,10M
2.根据上限和下限从一个Set中过滤出满足要求的元素集合.

实际这个是个很典型的技术要求, 之前的项目也遇见过,但是因为当时的类库不多, 都是直接手写实现的. 方式基本等同于第一个方式.

在这个过程中, 我写了四个方式, 基本记录到下面.
第一个方式:对Set进行迭代器遍历, 判断每个元素是否都在上限和下限范围中.如果满足则添加到结果集合中, 最后返回结果集合.
            测试效果:集合大小100K, 运算时间 3000ms+
过滤部分的逻辑如下:

 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     }

第二个方式: 借助TreeSet, 原始集合进行排序, 然后直接subset.
            测试效果: 集合大小10M, 运算时间: 12000ms+(获得TreeSet) , 200ms(获得结果)
过滤部分的逻辑如下(非常繁琐):

  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, 直接对于原始Set进行filter.
            测试效果:集合大小10M,过滤结果1M, 运算时间: 1000ms+
过滤部分的代码如下:

 1 //过滤的主体逻辑
 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   /* CollectionUtils.filter(targetSet, new Predicate() {
16    @Override
17    public boolean evaluate(Object o) {
18    BigDecimal bDObject = (BigDecimal) o;
19     return bDObject.compareTo(bdLower) >= 0
10                         && bDObject.compareTo(bdHigher) <= 0;
20    }
21    });*/
22     }

第四种方式:使用Guava(google Collections), 直接对于原始Set进行Filter
            测试效果:集合大小10M,过滤结果1M, 运算时间: 100ms-
过滤部分的代码如下:

 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     }

四种方式对比如下:
第一种方式:  仅依赖于JAVA原生类库 遍历时间最慢, 代码量很小
第二种方式:  仅依赖于JAVA原生类库 遍历时间比较慢(主要慢在生成有序Set), 代码量最多
第三种方式:  依赖于Apache Commons Collections, 遍历时间比较快, 代码量很少
第四种方式:  依赖于Guava, 遍历时间最快, 代码量很少

基于目前个人的技术水平和视野, 第四种方式可能是最佳选择.

记录一下, 以后可能还会有更好的方案.

一个简单的Java集合范围过滤的多个方式对比的更多相关文章

  1. 一个简单的Java web服务器实现

    前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...

  2. Java学习笔记 11/15:一个简单的JAVA例子

    首先来看一个简单的 Java 程序. 来看下面这个程序,试试看是否看得出它是在做哪些事情! 范例:TestJava.java   // TestJava.java,java 的简单范例  public ...

  3. Java入门篇(一)——如何编写一个简单的Java程序

    最近准备花费很长一段时间写一些关于Java的从入门到进阶再到项目开发的教程,希望对初学Java的朋友们有所帮助,更快的融入Java的学习之中. 主要内容包括JavaSE.JavaEE的基础知识以及如何 ...

  4. Ant—使用Ant构建一个简单的Java工程(两)

    博客<Ant-使用Ant构建一个简单的Java项目(一)>演示了使用Ant工具构建简单的Java项目,接着这个样例来进一步学习Ant: 上面样例须要运行多条ant命令才干运行Test类中的 ...

  5. IntelliJ IDEA创建一个简单的Java Project(二)

    1.  选择要创建的项目类型,同时配置本地的JDK 2. 是否使用模板创建项目 3. 选择项目在本地的存储位置 4. 点击Finish,完成一个简单的Java工程的创建.

  6. 利用 Docker 构建一个简单的 java 开发编译环境

    目前 Java 语言的版本很多,除了常用的 Java 8,有一些遗留项目可能使用了 Java 7,也可能有一些比较新的的项目使用了 Java 10 以上的版本.如果想切换自己本地的 Java 开发环境 ...

  7. 【Java】一个简单的Java应用程序

    简单记录,Java 核心技术卷I 基础知识(原书第10 版) 一个简单的Java应用程序"Hello, World!" Hello, World! Goodbye,World! 一 ...

  8. 一个简单的Java应用程序

    目录 一个简单的Java应用程序 首次运行结果 程序示例 运行结果 修改大小写之后的运行结果 程序示例 运行结果 关键字public 关键字class 类名及其命名规则 类名必须以字母开头 不能使用J ...

  9. 从一个简单的Java单例示例谈谈并发

    一个简单的单例示例 单例模式可能是大家经常接触和使用的一个设计模式,你可能会这么写 public class UnsafeLazyInitiallization { private static Un ...

随机推荐

  1. ide编码害死人

    1.从网上复制代码的时候不要直接复制代码到ide中(MyEclipse,Eclipse)中这样在一般的情况下就没问题,但是在有编码规则的时候需要特别的小心,建议先复制到本地的txt文件中,然后在复制到 ...

  2. hrbustoj 2130 一笔画(状态压缩)

    基础状态压缩 转移方程为 dp[j][i] = min(dp[j][i],dp[k][i^(1<<j)] + dis[k][j]); #include<iostream> #i ...

  3. ural1126 Magnetic Storms

    Magnetic Storms Time limit: 0.5 secondMemory limit: 64 MB The directory of our kindergarten decided ...

  4. gcd timer

    //0.创建队列 dispatch_queue_t queue = dispatch_get_global_queue(, ); NSLog(@"%s",__func__); // ...

  5. Tomcat(.jsp)

    定义: Tomcat服务器是一个免费的开放源代码的Web应用服务器.Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由 ...

  6. iframe与父页面的js通信

    1.父页面调用iframe中的函数: document.getElementById('myframe').contentWidow.fun1(); 2.在iframe中调用父页面中的函数: wind ...

  7. BigDecimal 高精度计算 熟悉扩展,java除法保留小数问题

    java保留两位小数问题: 方式一: 四舍五入  double   f   =   111231.5585;  BigDecimal   b   =   new   BigDecimal(f);  d ...

  8. sublime text3 Emmet (原zenCoding)安装方法

    1.安装使用Package Control组件安装 (1)打开控制台 (mac)control+`; (win)ctrl+` (2)复制一下代码并回车 import urllib.request,os ...

  9. javascript模拟鼠标双击事件

    通常我们在做开发的时候需要通过单击切换对立事件,简单做了一个模型. <!DOCTYPE html> <html> <head> <title>javas ...

  10. [iOS Animation]-CALayer 性能优化

    性能优化 代码应该运行的尽量快,而不是更快 - 理查德 在第一和第二部分,我们了解了Core Animation提供的关于绘制和动画的一些特性.Core Animation功能和性能都非常强大,但如果 ...