我正在为这样一个简单的类实现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
}
我希望这些对象的natural ordering是: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);
}
这就行了,但我对这段代码不太满意.诚然,它并不复杂,但相当冗长乏味.
问题是,how would you make this less verbose(同时保留功能)?如果Java标准库或Apache Commons有帮助,请随时参考.让这个(稍微)简单一点的唯一 Select 是实现我自己的"NullSafeStringComparator",并将其应用于比较这两个字段吗?
Edits 1-3:埃迪是对的;修正了上面的"两个名字都是空的"情况
关于公认的答案
我在2009年在Java1.6上问过这个问题,当时100是我首选的答案.直到现在(2017年),我才抽出时间来改变这一点.
还有3rd party library solutions个-2009年的Apache Commons Colltions One和2013年的Guava One,都是我发布的-在某个时候我确实更喜欢.
我现在把答案说清楚了.如果是在Java8上,这肯定是首选,现在Java8应该可以用于几乎所有的项目.