您的位置:首页 > 大数据 > 人工智能

guava学习(一)ComparisonChain 源码分析

2015-04-27 16:52 281 查看
1. ComparisonChain 使用

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。很巧妙,有木有。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: