如何简化空安全的compareTo()实现?

2023-12-20

我正在实施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);
}

这完成了工作,但我对这段代码并不完全满意。诚然不是very复杂,但相当冗长乏味。

问题是,你如何让这个变得不那么冗长(同时保留功能)?如果有帮助,请随意参考 Java 标准库或 Apache Commons。使这个(稍微)更简单的唯一选择是实现我自己的“NullSafeStringComparator”,并将其应用于比较两个字段吗?

编辑1-3:艾迪是对的;修复了上面的“两个名字都为空”的情况

关于已接受的答案

我在 2009 年问过这个问题,当然是在 Java 1.6 上,当时Eddie 的纯 JDK 解决方案 https://stackoverflow.com/a/481836/56285是我首选接受的答案。直到现在(2017 年)我才抽出时间来改变这一点。

还有第三方图书馆解决方案 https://stackoverflow.com/a/500643/56285— 2009 年的 Apache Commons Collections 和 2013 年的 Guava 都由我发布 — 在某些时候我确实更喜欢它们。

我现在已经清理干净了Lukasz Wiktor 的 Java 8 解决方案 https://stackoverflow.com/a/23908426/56285接受的答案。如果在 Java 8 上,这绝对是首选,而且现在 Java 8 应该可用于几乎所有项目。


你可以简单地使用阿帕奇公共语言 http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ObjectUtils.html#compare(T,%20T):

result = ObjectUtils.compare(firstComparable, secondComparable)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何简化空安全的compareTo()实现? 的相关文章

随机推荐