如何简化一个null安全的compareTo()实现? [英] How to simplify a null-safe compareTo() implementation?

查看:4409
本文介绍了如何简化一个null安全的compareTo()实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为一个简单的类实现 compareTo()方法(以便能够使用 Collections.sort()和由Java平台提供的其他好处):

I'm implementing compareTo() method for a simple class such as this (to be able to use Collections.sort() and other goodies offered by the Java platform):

public class Metadata implements Comparable<Metadata> {
    private String name;
    private String value;

// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}

我想要这些对象的自然排序是:1)按名称排序,2)如果名称相同,按值排序;两个比较应该不区分大小写。对于这两个字段,空值是完全可以接受的,因此 compareTo 在这些情况下不能断开。

I want the natural ordering for these objects to be: 1) sorted by name and 2) sorted by value if name is the same; both comparisons should be case-insensitive. For both fields null values are perfectly acceptable, so compareTo must not break in these cases.

想起来的解决方案是沿着下面的线路(我在这里使用保护子句,而其他人可能更喜欢单个返回点,但在旁边

The solution that springs to mind is along the lines of the following (I'm using "guard clauses" here while others might prefer a single return point, but that's beside the point):

// 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);
}

这样做,但我不太满意这个代码。诚然,这不是很复杂,但是很冗长和繁琐。

This does the job, but I'm not perfectly happy with this code. Admittedly it isn't very complex, but is quite verbose and tedious.

问题是, verbose (保留功能)?如果他们帮助,请随意参考Java标准库或Apache Commons。这个(一点点)简单的唯一选项是实现我自己的NullSafeStringComparator,并应用它来比较这两个字段?

The question is, how would you make this less verbose (while retaining the functionality)? Feel free to refer to Java standard libraries or Apache Commons if they help. Would the only option to make this (a little) simpler be to implement my own "NullSafeStringComparator", and apply it for comparing both fields?

3 :Eddie的权利;固定两个名称都为null上面的情况

Edits 1-3: Eddie's right; fixed the "both names are null" case above

推荐答案

可能有一个实现,但这是很直接的实现,我一直滚动自己的。

I would implement a null safe comparator. There may be an implementation out there, but this is so straightforward to implement that I've always rolled my own.

注意:您的比较器如果两个名称都为null,甚至不会比较值字段。我不认为这是你想要的。

Note: Your comparator above, if both names are null, won't even compare the value fields. I don't think this is what you want.

我会用下面的方法实现:

I would implement this with something like the following:

// primarily by name, secondarily by value; null-safe; case-insensitive
public int compareTo(final Metadata other) {

    if (other == null) {
        throw new NullPointerException();
    }

    int result = nullSafeStringComparator(this.name, other.name);
    if (result != 0) {
        return result;
    }

    return nullSafeStringComparator(this.value, other.value);
}

public static int nullSafeStringComparator(final String one, final String two) {
    if (one == null ^ two == null) {
        return (one == null) ? -1 : 1;
    }

    if (one == null && two == null) {
        return 0;
    }

    return one.compareToIgnoreCase(two);
}

编辑:修改代码示例中的拼写错误。这是我不先测试它。

Fixed typos in code sample. That's what I get for not testing it first!

编辑:推荐nullSafeStringComparator为静态。

Promoted nullSafeStringComparator to static.

这篇关于如何简化一个null安全的compareTo()实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆