接下来我们会讲到辅助类,首先看Comparator组。
ReverseComparator
ComparatorChain
NullComparator
FixedOrderComparator
ComparatorUtils
其实Comparator这个概念并不是Commons Collections引入的,在标准的Java Collections API中,已经明确定了一个java.util.Comparator接口,只是有很多人并不了解,Commons Collections也只是扩展了这个接口而已。这个java.util.Comparator定义如下核心方法:
public int compare(Object arg0, Object arg1)
传给它两个对象,它要告诉我们这两个对象哪一个在特定的语义下更“大”,或者两者相等。如果arg0 > arg1,返回大于0的整数;如果arg0 = arg1,返回0;如果arg0 < arg2,返回小于0的整数。
我们看看Commons Collections给我们提供了哪些Comparator的实现类(都在org.apache.commons.collections.comparators包下面):
BooleanComparator – 用于排序一组Boolean对象,指明先true还是先false;
ComparableComparator – 用于排序实现了java.lang.Comparable接口的对象(我们常用的Java类如String、Integer、Date、Double、File、Character等等都实现了Comparable接口);
ComparatorChain – 定义一组Comparator链,链中的Comparator对象会被依次执行;
FixedOrderComparator – 用于定义一个特殊的顺序,对一组对象按照这样的自定义顺序进行排序;
NullComparator – 让null值也可参与比较,可以设定为先null或者后null;
ReverseComparator – 将原有的Comparator效果反转;
TransformingComparator – 将一个Comparator装饰为具有Transformer效果的Comparator。
// 有关Transformer的内容会在以后的笔记中讲到。
以上除了ComparatorChain之外,似乎都是实现一些很基本的比较方法,但是当我们用ComparatorChain将一组Comparator串起来之后,就可以实现非常灵活的比较操作。那么这些Comparator在实际代码中如何使用呢?看例子:
/** Issue.java */
package sean.study.commons.collections;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
public class Issue {
private long id;
private String severity;
private String owner;
public Issue() {
}
public Issue(long id, String severity, String owner) {
this.id = id;
this.severity = severity;
this.owner = owner;
}
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("id", id)
.append("severity", severity)
.append("owner", owner)
.toString();
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getSeverity() {
return severity;
}
public void setSeverity(String severity) {
this.severity = severity;
}
}
/** ComparatorUsage.java */
package sean.study.commons.collections;
import java.util.Arrays;
import java.util.Comparator;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.comparators.ComparatorChain;
import org.apache.commons.collections.comparators.FixedOrderComparator;
import org.apache.commons.lang.StringUtils;
public class ComparatorUsage {
public static void main(String[] args) {
demoComparator();
}
public static void demoComparator() {
System.out.println(StringUtils.center(" demoComparator ", 40, "="));
// data setup
Issue[] issues = new Issue[] {
new Issue(15102, "Major", "John"),
new Issue(15103, "Minor", "Agnes"),
new Issue(15104, "Critical", "Bill"),
new Issue(15105, "Major", "John"),
new Issue(15106, "Major", "John"),
new Issue(15107, "Critical", "John"),
new Issue(15108, "Major", "Agnes"),
new Issue(15109, "Minor", "Julie"),
new Issue(15110, "Major", "Mary"),
new Issue(15111, "Enhancement", "Bill"),
new Issue(15112, "Minor", "Julie"),
new Issue(15113, "Major", "Julie")
};
// comparators setup
String[] severityOrder = {"Critical", "Major", "Minor", "Enhancement"};
Comparator severityComparator = new FixedOrderComparator(severityOrder);
ComparatorChain compChain = new ComparatorChain();
compChain.addComparator(new BeanComparator("owner"));
compChain.addComparator(new BeanComparator("severity", severityComparator));
compChain.addComparator(new BeanComparator("id"));
// sort and display
Arrays.sort(issues, compChain);
for (int i = 0; i < issues.length; i++) {
System.out.println(issues[i]);
}
System.out.println(StringUtils.repeat("=", 40));
}
}
输出结果为:
============ demoComparator ============
Issue[id=15108,severity=Major,owner=Agnes]
Issue[id=15103,severity=Minor,owner=Agnes]
Issue[id=15104,severity=Critical,owner=Bill]
Issue[id=15111,severity=Enhancement,owner=Bill]
Issue[id=15107,severity=Critical,owner=John]
Issue[id=15102,severity=Major,owner=John]
Issue[id=15105,severity=Major,owner=John]
Issue[id=15106,severity=Major,owner=John]
Issue[id=15113,severity=Major,owner=Julie]
Issue[id=15109,severity=Minor,owner=Julie]
Issue[id=15112,severity=Minor,owner=Julie]
Issue[id=15110,severity=Major,owner=Mary]
========================================
我们可以看到,ComparatorChain中的Comparator被依次执行,先按name,再按我们自定义的severity次序,再按id,最终我们得到了重新排列的数组。
# re: [Jakarta Commons笔记] Commons Collections - Comparator组 回复
ReverseComparator
ComparatorChain
NullComparator
是三个极重要的功能,JDK里面居然不提供标准实现真是太离谱了,幸亏有Commons