java compare null,如何简化一个null安全的compareTo()实现?

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 {

private String name;

private String value;

// Imagine basic constructor and accessors here

// Irrelevant parts omitted

}

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.

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?

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.

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

}

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

EDIT: Promoted nullSafeStringComparator to static.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值