我正在compareTo()
为这样的简单类实现方法(以便能够使用Collections.sort()
和Java平台提供的其他功能):
public class Metadata implements Comparable<Metadata> {
private String name;
private String value;
// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}
我希望这些对象的自然排序是:1)按名称排序,以及2)如果名称相同,则按值排序;两种比较均应不区分大小写。对于这两个字段,空值都是完全可以接受的,因此compareTo
在这些情况下不得中断。
我想到的解决方案是遵循以下思路的(我在这里使用“保护子句”,而其他人可能更喜欢单个返回点,但是这很重要):
// primarily by name, secondarily by value; null-safe; case-insensitive
public int compareTo(Metadata other) {
if (this.name == null && other.name != null){
return -1;
}
else if (this.name != null && other.name == null){
return 1;
}
else if (this.name != null && other.name != null) {
int result = this.name.compareToIgnoreCase(other.name);
if (result != 0){
return result;
}
}
if (this.value == null) {
return other.value == null ? 0 : -1;
}
if (other.value == null){
return 1;
}
return this.value.compareToIgnoreCase(other.value);
}
这可以完成工作,但是我对这段代码并不完全满意。诚然,它不是很复杂,但是非常冗长乏味。
问题是,如何使它变得不太冗长(同时保留功能)?如果有帮助,请随时参考Java标准库或Apache Commons。使这个(稍微)简单一点的唯一选择是实现自己的“ NullSafeStringComparator”并将其应用于比较两个字段吗?
编辑1-3:埃迪的权利;修复了上面的“名字都为空”的情况
关于接受的答案
我早在2009年就在Java 1.6上问了这个问题,当时我首选的是Eddie的纯JDK解决方案。直到现在(2017年),我再也没有回过头来改变它。
也有第三方库的解决方案 -a 2009年阿帕奇百科全书集合一年2013番石榴一个,两张贴由我,那我也喜欢在某个时间点。
现在,我将Lukasz Wiktor的干净Java 8解决方案作为了公认的答案。如果在Java 8上,那绝对应该是首选,现在,Java 8应该可以用于几乎所有项目。