我使用下面的方法首先在Object.property1上对Map进行排序,然后对每个Object.property1进行排序,按Object.property2排序。
例如,
property1 = TaxIdNumber和
property2 = ProviderName
我只是想知道这可以用更短更精确的方式完成。任何帮助或建议将不胜感激。
private List<TestObject> sortByValue(final Map m) {
List<TestObject> values = new ArrayList<TestObject>();
values.addAll(m.values());
// First sort the list by Tax ID.
Collections.sort(values, new Comparator<TestObject>() {
public int compare(TestObject r1, TestObject r2) {
Long taxId1 = (r1 == null ? null : r1.getTaxIdNumber());
Long taxId2 = (r2 == null ? null : r2.getTaxIdNumber());
if (taxId1 == null || taxId2 == null) {
return 0;
}
return taxId1.compareTo(taxId2);
}
});
// Then sort the list by Provider name.
Collections.sort(values, new Comparator<TestObject>() {
public int compare(TestObject r1, TestObject r2) {
String name1 = (r1 == null ? null : r1.getProviderName());
String name2 = (r2 == null ? null : r2.getProviderName());
if (name1 == null || name2 == null) {
return 0;
}
if (r1.getTaxIdNumber() == r2.getTaxIdNumber()) {
return name1.compareTo(name2);
} else {
return 0;
}
}
});
return values;
}
答案 0 :(得分:2)
你只需要一个比较器。首先比较出租车。如果它们是不等的,则返回-1或1。如果它们相等,则比较提供者名称。
类似的东西:
Collections.sort(values, new Comparator<TestObject>() {
public int compare(TestObject r1, TestObject r2) {
Long taxId1 = (r1 == null ? null : r1.getTaxIdNumber());
Long taxId2 = (r2 == null ? null : r2.getTaxIdNumber());
if (taxId1 == null || taxId2 == null) {
return 0;
}
int cmp = taxId1.compareTo(taxId2);
if (cmp != 0)
return cmp;
String name1 = (r1 == null ? null : r1.getProviderName());
String name2 = (r2 == null ? null : r2.getProviderName());
if (name1 == null || name2 == null) {
return 0;
}
return name1.compareTo(name2);
}
});
答案 1 :(得分:2)
您的空值处理违反了compare
的约定,因为您认为null
等于任何其他值,而JavaDoc写道:
比较其订单的两个参数。当第一个参数小于,等于或大于第二个参数时,返回负整数,零或正整数。
,特别是:
最后,实施者必须确保
compare(x, y)==0
暗示所有z都sgn(compare(x, z))
==sgn(compare(y, z))
。
您的代码无法为x = null
,y = "a"
,z = "b"
完成。
因此,如果列表中的任何对象或属性为null
,则列表可能无法正确排序。
话虽如此,我想知道列表是否真的包含null
值或属性?如果没有,我将删除所有null
项检查,最后以
Collections.sort(list, new Comparator<TestObject>() {
@Override public int compare(TestObject o1, TestObject o2) {
int c = o1.getTaxIdNumber().compareTo(o2.getTaxIdNumber);
if (c != 0) {
return c;
}
return o1.getProviderName().compareTo(o2.getProviderName());
}
}
如果列表可能包含null
个对象或属性,则必须定义null
值是先到还是最后,并相应地扩展比较器:
Collections.sort(list, new Comparator<TestObject>() {
@Override public int compare(TestObject o1, TestObject o2) {
// insert null-checks for o1, o2 here
int c = cmp(getTaxIdNumber(), o2.getTaxIdNumber());
if (c != 0) {
return c;
}
return cmp(o1.getProviderName(), o2.getProviderName());
}
private <T extends Comparable<? super T>> cmp(T o1, T o2) {
if (o1 == o2) {
return 0;
else if (o1 == null) {
return -1;
} else if (o2 == null) {
return 1;
} else {
return o1.compareTo(o2);
}
}
}
现在这是一个相当多的重复和棘手的代码,这就是为什么Apache的人写了CompareToBuilder。使用该API,您只需编写:
@Override int compare(TestObject r1, TestObject r2) {
// insert null checks for r1 and r2 here - if you really need them
return new CompareToBuilder()
.append(r1.getTaxIdNumber(), r2.getTaxIdNumber())
.append(r1.getProviderName(), r2.getProviderName())
.toComparison();
}
}