一个简单的Java集合范围过滤的多个方式对比
在一个项目里面有这么一个技术需求:
1.集合中元素个数,10M
2.根据上限和下限从一个Set中过滤出满足要求的元素集合.
实际这个是个很典型的技术要求, 之前的项目也遇见过,但是因为当时的类库不多, 都是直接手写实现的. 方式基本等同于第一个方式.
在这个过程中, 我写了四个方式, 基本记录到下面.
第一个方式:对Set进行迭代器遍历, 判断每个元素是否都在上限和下限范围中.如果满足则添加到结果集合中, 最后返回结果集合.
测试效果:集合大小100K, 运算时间 3000ms+
过滤部分的逻辑如下:
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(获得结果)
过滤部分的逻辑如下(非常繁琐):
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+
过滤部分的代码如下:
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);
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-
过滤部分的代码如下:
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集合范围过滤的多个方式对比的更多相关文章
- 一个简单的Java web服务器实现
前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...
- Java学习笔记 11/15:一个简单的JAVA例子
首先来看一个简单的 Java 程序. 来看下面这个程序,试试看是否看得出它是在做哪些事情! 范例:TestJava.java // TestJava.java,java 的简单范例 public ...
- Java入门篇(一)——如何编写一个简单的Java程序
最近准备花费很长一段时间写一些关于Java的从入门到进阶再到项目开发的教程,希望对初学Java的朋友们有所帮助,更快的融入Java的学习之中. 主要内容包括JavaSE.JavaEE的基础知识以及如何 ...
- Ant—使用Ant构建一个简单的Java工程(两)
博客<Ant-使用Ant构建一个简单的Java项目(一)>演示了使用Ant工具构建简单的Java项目,接着这个样例来进一步学习Ant: 上面样例须要运行多条ant命令才干运行Test类中的 ...
- IntelliJ IDEA创建一个简单的Java Project(二)
1. 选择要创建的项目类型,同时配置本地的JDK 2. 是否使用模板创建项目 3. 选择项目在本地的存储位置 4. 点击Finish,完成一个简单的Java工程的创建.
- 利用 Docker 构建一个简单的 java 开发编译环境
目前 Java 语言的版本很多,除了常用的 Java 8,有一些遗留项目可能使用了 Java 7,也可能有一些比较新的的项目使用了 Java 10 以上的版本.如果想切换自己本地的 Java 开发环境 ...
- 【Java】一个简单的Java应用程序
简单记录,Java 核心技术卷I 基础知识(原书第10 版) 一个简单的Java应用程序"Hello, World!" Hello, World! Goodbye,World! 一 ...
- 一个简单的Java应用程序
目录 一个简单的Java应用程序 首次运行结果 程序示例 运行结果 修改大小写之后的运行结果 程序示例 运行结果 关键字public 关键字class 类名及其命名规则 类名必须以字母开头 不能使用J ...
- 从一个简单的Java单例示例谈谈并发
一个简单的单例示例 单例模式可能是大家经常接触和使用的一个设计模式,你可能会这么写 public class UnsafeLazyInitiallization { private static Un ...
随机推荐
- jQuery+CSS实现的图片滚动效果
http://www.helloweba.com/view-blog-139.html
- HDU 1754 I Hate It(线段树基础应用)
基础线段树 #include<iostream> #include<cstdio> #include<cstring> using namespace std; # ...
- 随机获取部分List<Object>集合
随机返回list对象 /** * 返回随机List * @param list 备选 * @param selected 备选数量 * @return */ public List getRandom ...
- JS对象引用
对象和函数都是引用的关系(改变后者会改变前者) 但是下面这个列子情况不一样了.刚开始的时候 B 引用了 A的地址,后来B又重新赋值,新占了一个地址,A B俩的关系已经脱离. 那么有的时候,我们只有 ...
- Java中的数组越界问题
Java中数组初始化和OC其实是一样的,分为动态初始化和静态初始化, 动态初始化:指定长度,由系统给出初始化值 静态初始化:给出初始化值,由系统给出长度 在我们使用数组时最容易出现的就是数组越界问题, ...
- Vim 命令 (转)
上图引用自何处忘记了,不好意思. 基础快捷键 normal模式下 快速查找 fa → 到下一个为a的字符处,你也可以fs到下一个为s的字符. t, → 到逗号前的第一个字符.逗号可以变成其它字 ...
- 多机并行计算框架 和CoolHash数据库(可用于多机机器学习)
http://my.oschina.net/fourinone/blog/289122 http://www.oschina.net/p/fourinone
- C++异常(exception)第三篇-------如何释放资源(没有finally语句)
问题: C++中没有finally,那么应该在哪里关闭资源? C++的try{}catch(){},为什么没有finally{}块来释放资源? 如类中的一个方法,局部变量 File * file=NU ...
- JQuery实现超链接鼠标提示效果
一.第一种方法用Jquery<p><a href="http://www.nowamagic.net/" class="tooltip" ti ...
- POJ 3362 Protecting the Flowers
这题和金华区域赛A题(HDU 4442)是一样的做法. 对两个奶牛进行分析,选择两个奶牛总花费少的方式排序. bool cmp(const X&a,const X&b){ return ...