guava学习(一)ComparisonChain 源码分析
2015-04-27 16:52
281 查看
1. ComparisonChain 使用
2. ComparisonChain 源码分析
ComparisonChain 使用
我有一个产品的list,想对这个list先按产品生效时间排序,如果生效时间一样再按失效时间排序,代码如下:
ComparisonChain 源码分析
上面的例子中最关键的一句代码就是:
这是一连串方法,先是start,然后是若干个compare,最后是result
先看下start
自然的看下ACTIVE的定义
这个ACTIVE 还是比较好理解的,第一步是做比较:left.compareTo(right),然后做classify,看看classify怎么写的
ComparisonChain classify(int result) {
return (result < 0) ? LESS : (result > 0) ? GREATER : ACTIVE;
}
如果我们比较的结果是相等,那返回的是ACTIVE,如果chain到这就结束了,ACTIVE的result方法return 0;如果后面还有compare方法,那就继续做比较。可见ACTIVE是个比较器。
而如果这个比较器返回的结果是not equal,我们需要再看下LESS 和GREATER 的定义了
走到这里,那我们就继续看InactiveComparisonChain怎么实现的喽
如果某一个compare方法比较的结果是not equal,这里相当于整个chain已经有了result,只是要把this一直传递到最后调用它自己的result就可以了。
而这里result正是“-1”或“1”。而如果一开始比较是equal,则返回的是ACTIVE,则会走后面的节点继续compare。
总结一下,ACTIVE和LESS GREATER 都继承了ComparisonChain,ACTIVE是比较器,LESS或者GREATER是单纯的传递器,向后传递结果。如果equal,返回一个比较器,后面继续进行比较,如果not equal,则返回一个传递器,直接把结果传递到最后执行result。很巧妙,有木有。
2. ComparisonChain 源码分析
ComparisonChain 使用
我有一个产品的list,想对这个list先按产品生效时间排序,如果生效时间一样再按失效时间排序,代码如下:
package collection; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import com.google.common.collect.ComparisonChain; public class TestListSort { public static void main(String[] args) { List<Product> list = new ArrayList<Product>(); Product prod1 = new Product(new Date(2015, 4, 21), new Date(2015, 4, 22), 1); list.add(prod1); Product prod2 = new Product(new Date(2015, 4, 21), new Date(2015, 4, 21), 2); list.add(prod2); Product prod3 = new Product(new Date(2015, 4, 20), new Date(2015, 4, 21), 3); list.add(prod3); printList(list); sort(list); printList(list); } public static void sort(List<Product> list){ Collections.sort(list,new Comparator<Product>() { @Override public int compare(Product p1, Product p2) { return ComparisonChain.start().compare(p1.getValid(), p2.getValid()). compare(p1.getExpire(), p2.getExpire()).result(); } }); } public static void printList(List<Product> list){ for(int i = 0;i<list.size();i++){ System.out.println("id:"+list.get(i).getId()+" valid:"+list.get(i).getValid() +" expire:"+list.get(i).getExpire()); } } } class Product { private Date valid; private Date expire; private int id; Product(Date valid, Date expire, int id) { this.valid = valid; this.expire = expire; this.id = id; } public Date getValid() { return valid; } public void setValid(Date valid) { this.valid = valid; } public Date getExpire() { return expire; } public void setExpire(Date expire) { this.expire = expire; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
ComparisonChain 源码分析
上面的例子中最关键的一句代码就是:
return ComparisonChain.start().compare(p1.getValid(), p2.getValid()).compare(p1.getExpire(),p2.getExpire()).result();
这是一连串方法,先是start,然后是若干个compare,最后是result
先看下start
/** * Begins a new chained comparison statement. See example in the class * documentation. */ public static ComparisonChain start() { return ACTIVE; }
自然的看下ACTIVE的定义
private static final ComparisonChain ACTIVE = new ComparisonChain() { @SuppressWarnings("unchecked") @Override public ComparisonChain compare( Comparable left, Comparable right) { return classify(left.compareTo(right)); } @Override public <T> ComparisonChain compare( @Nullable T left, @Nullable T right, Comparator<T> comparator) { return classify(comparator.compare(left, right)); } @Override public ComparisonChain compare(int left, int right) { return classify(Ints.compare(left, right)); } @Override public ComparisonChain compare(long left, long right) { return classify(Longs.compare(left, right)); } @Override public ComparisonChain compare(float left, float right) { return classify(Float.compare(left, right)); } @Override public Co 4000 mparisonChain compare(double left, double right) { return classify(Double.compare(left, right)); } @Override public ComparisonChain compareTrueFirst(boolean left, boolean right) { return classify(Booleans.compare(right, left)); // reversed } @Override public ComparisonChain compareFalseFirst(boolean left, boolean right) { return classify(Booleans.compare(left, right)); } ComparisonChain classify(int result) { return (result < 0) ? LESS : (result > 0) ? GREATER : ACTIVE; } @Override public int result() { return 0; } };
这个ACTIVE 还是比较好理解的,第一步是做比较:left.compareTo(right),然后做classify,看看classify怎么写的
ComparisonChain classify(int result) {
return (result < 0) ? LESS : (result > 0) ? GREATER : ACTIVE;
}
如果我们比较的结果是相等,那返回的是ACTIVE,如果chain到这就结束了,ACTIVE的result方法return 0;如果后面还有compare方法,那就继续做比较。可见ACTIVE是个比较器。
而如果这个比较器返回的结果是not equal,我们需要再看下LESS 和GREATER 的定义了
private static final ComparisonChain LESS = new InactiveComparisonChain(-1); private static final ComparisonChain GREATER = new InactiveComparisonChain(1);
走到这里,那我们就继续看InactiveComparisonChain怎么实现的喽
private static final class InactiveComparisonChain extends ComparisonChain { final int result; InactiveComparisonChain(int result) { this.result = result; } @Override public ComparisonChain compare( @Nullable Comparable left, @Nullable Comparable right) { return this; } @Override public <T> ComparisonChain compare(@Nullable T left, @Nullable T right, @Nullable Comparator<T> comparator) { return this; } @Override public ComparisonChain compare(int left, int right) { return this; } @Override public ComparisonChain compare(long left, long right) { return this; } @Override public ComparisonChain compare(float left, float right) { return this; } @Override public ComparisonChain compare(double left, double right) { return this; } @Override public ComparisonChain compareTrueFirst(boolean left, boolean right) { return this; } @Override public ComparisonChain compareFalseFirst(boolean left, boolean right) { return this; } @Override public int result() { return result; } }
如果某一个compare方法比较的结果是not equal,这里相当于整个chain已经有了result,只是要把this一直传递到最后调用它自己的result就可以了。
而这里result正是“-1”或“1”。而如果一开始比较是equal,则返回的是ACTIVE,则会走后面的节点继续compare。
总结一下,ACTIVE和LESS GREATER 都继承了ComparisonChain,ACTIVE是比较器,LESS或者GREATER是单纯的传递器,向后传递结果。如果equal,返回一个比较器,后面继续进行比较,如果not equal,则返回一个传递器,直接把结果传递到最后执行result。很巧妙,有木有。
相关文章推荐
- [Guava源码分析]Objects 和 ComparisonChain:帮助重写Object方法
- Android内核学习之三----------Power源码分析学习(1)
- 详解关于Lua源码分析学习教程
- EasyUI学习笔记(五)——学习读源码--parser源码阅读分析1
- HLS学习(二)HLSDownloader源码分析(1)介绍
- Hadoop-2.4.1学习之创建fsimage和edits源码分析
- 我的内核学习笔记10:Intel GPIO驱动源码分析
- Weka 3.7.12源码学习、阅读、分析(1)
- spark源码学习(三)---worker源码分析-worker启动driver、executor分析
- spark源码学习(四)---job执行分析
- Guava源码学习(五)EventBus
- Android FM模块学习之四源码分析(八)
- 仿美团项目学习源码分析(2)---JS之slice()方法
- AndroidFM模块学习之四源码分析(九)
- 读白刃underscore疑惑分析--underscore源码学习一
- 【原创】动态图像监测开源代码 motion 学习 ----- Motion源码分析(1)
- CowNew开源学习文档-hibernate 的HQL源码分析1
- Ceph 学习——OSD读写流程与源码分析(一)
- Struts2学习(第四篇)——struts2中action执行流程和源码分析
- EasyUI学习总结(四)——parser源码分析