关于空值的可比合同和比较合同
Comparable
合约指定 e.compareTo(null)
必须抛出 NullPointerException
。
来自API:
请注意,
null
不是任何类的实例,并且e.compareTo(null)
应该抛出NullPointerException
,即使>e.equals(null)
返回false
。
另一方面,比较器
API 没有提及比较 null
时需要发生的情况。考虑以下通用方法的尝试,该方法采用 Comparable
,并为其返回一个 Comparator
,并将 null
作为最小元素。
static <T extends Comparable<? super T>> Comparator<T> nullComparableComparator() {
return new Comparator<T>() {
@Override public int compare(T el1, T el2) {
return
el1 == null ? -1 :
el2 == null ? +1 :
el1.compareTo(el2);
}
};
}
这允许我们执行以下操作:
List<Integer> numbers = new ArrayList<Integer>(
Arrays.asList(3, 2, 1, null, null, 0)
);
Comparator<Integer> numbersComp = nullComparableComparator();
Collections.sort(numbers, numbersComp);
System.out.println(numbers);
// "[null, null, 0, 1, 2, 3]"
List<String> names = new ArrayList<String>(
Arrays.asList("Bob", null, "Alice", "Carol")
);
Comparator<String> namesComp = nullComparableComparator();
Collections.sort(names, namesComp);
System.out.println(names);
// "[null, Alice, Bob, Carol]"
因此问题是:
- 这是
Comparator
的可接受使用,还是违反了关于比较null
和抛出的不成文规则>空指针异常
? - 甚至必须对包含
null
元素的List
进行排序是否是一个好主意,或者这是设计错误的明确标志?
Comparable
contract specifies that e.compareTo(null)
must throw NullPointerException
.
From the API:
Note that
null
is not an instance of any class, ande.compareTo(null)
should throw aNullPointerException
even thoughe.equals(null)
returnsfalse
.
On the other hand, Comparator
API mentions nothing about what needs to happen when comparing null
. Consider the following attempt of a generic method that takes a Comparable
, and return a Comparator
for it that puts null
as the minimum element.
static <T extends Comparable<? super T>> Comparator<T> nullComparableComparator() {
return new Comparator<T>() {
@Override public int compare(T el1, T el2) {
return
el1 == null ? -1 :
el2 == null ? +1 :
el1.compareTo(el2);
}
};
}
This allows us to do the following:
List<Integer> numbers = new ArrayList<Integer>(
Arrays.asList(3, 2, 1, null, null, 0)
);
Comparator<Integer> numbersComp = nullComparableComparator();
Collections.sort(numbers, numbersComp);
System.out.println(numbers);
// "[null, null, 0, 1, 2, 3]"
List<String> names = new ArrayList<String>(
Arrays.asList("Bob", null, "Alice", "Carol")
);
Comparator<String> namesComp = nullComparableComparator();
Collections.sort(names, namesComp);
System.out.println(names);
// "[null, Alice, Bob, Carol]"
So the questions are:
- Is this an acceptable use of a
Comparator
, or is it violating an unwritten rule regarding comparingnull
and throwingNullPointerException
? - Is it ever a good idea to even have to sort a
List
containingnull
elements, or is that a sure sign of a design error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Comparable
不允许null
的原因很简单:对于所有对象
a
和b
,其中!a。等于(b)。更具体地说:
必须评估为
true
才能满足相关合同。因此
null
是不允许的,因为您不能这样做:Comparator
更灵活,因此对null
的处理是一个特定于实现的问题。支持与否取决于您希望Comparator
做什么。Comparable
doesn't allownull
simply because:for all objects
a
andb
where!a.equals(b)
. More specifically:must evaluate to
true
to satisfy the relevant contracts.So
null
isn't allowed because you can't do:Comparator
is more flexible so handling ofnull
is an implementation-specific issue. Support it or not depending on what you want yourComparator
to do.从概念上讲,null 意味着“什么都没有”,在列表中放置任何内容对我来说似乎很奇怪。此外,Java List 合约指出
,因此 Java 中的 List 实现根本不需要支持 null 元素。总而言之,如果您没有充分的理由将 null 放入列表中,请不要将 null 放入列表中,如果这样做,请测试它是否确实按预期工作。
Conceptually, null means "nothing", and placing nothing in a list seems weird to me. Also, the Java List contract states that
so a List implementation in Java is not even required to support null elements at all. To sum up, if you do not have a good reason to put null into a list, don't, and if you do, test that it actually works as expected.
好吧,列表包含空对象可能没有意义,但您的列表可能包含“业务对象”,并且您可以对业务对象的不同属性进行排序,其中一些属性可能包含空值。
BeanComparator 允许您对企业中的属性进行排序对象,即使属性包含 null,所以我不得不说这是比较器的可接受的使用。
Well, it probably doesn't make sense for the list to contain a null Object, but maybe your List contains a "business object" and you can sort on different properties of the business object, some of which may contain nulls.
The BeanComparator allows you to sort on a propery in a business object even if the property contains null, so I would have to say it is an acceptable use of a Comparator.