我正在为诸如此类的简单类实现 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:Eddie 是对的;修复了上面的“两个名字都为空”的情况
关于接受的答案
我在 2009 年问过这个问题,当然是在 Java 1.6 上,当时 the pure JDK solution by Eddie 是我首选的接受答案。直到现在(2017 年),我才开始改变它。
还有3rd party library solutions ——一个 2009 年的 Apache Commons Collections 和一个 2013 年的 Guava,都是我发布的——我确实更喜欢在某个时间点。
我现在做了干净的 Java 8 solution by Lukasz Wiktor 接受的答案。如果在 Java 8 上,这绝对应该是首选,而且现在几乎所有项目都应该使用 Java 8。
最佳答案
您可以简单地使用 Apache Commons Lang :
result = ObjectUtils.compare(firstComparable, secondComparable)
关于java - 如何简化 null 安全的 compareTo() 实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/481813/