Comparable和Comparator关于null的合同 [英] Comparable and Comparator contract with regards to null
问题描述
Comparable
contract指定 e.compareTo(null)
必须抛出 NullPointerException
。
来自 API :
$ b
请注意
null
不是任何类的实例,并且e.compareTo(null)
应该抛出NullPointerException
甚至虽然e.equals(null)
返回false
。
另一方面, Comparator
API 没有提及比较 null
时需要发生什么。考虑以下尝试使用 Comparable
的泛型方法,并返回一个 Comparator
,它将<$ c
static< T extends Comparable <?c> null
作为最小元素。 super T>>比较< T> nullComparableComparator(){
return new Comparator< T>(){
@Override public int compare(T el1,T el2){
return
el1 == null? -1:
el2 == null? +1:
el1.compareTo(el2);
}
};
}
这可以让我们做到以下几点:
列表<整数> numbers = new ArrayList< Integer>(
Arrays.asList(3,2,1,null,null,0)
);
比较器<整数> 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)
);
比较器< String> namesComp = nullComparableComparator();
Collections.sort(names,namesComp);
System.out.println(names);
//[null,Alice,Bob,Carol]
:
null
和抛出 NullPointerException
?
null
元素的 List
进行排序,或者这是设计错误的明确标志?
可比较
不会允许 null
,因为:
a.compareTo(b)== -b.compareTo(a)所有对象的
a
和 b
其中!a.equals(b)
。更具体地说:
a.equals(b)? b.equals(a)&& a.compareTo(b)== 0&&
b.compareTo(a)== 0&& a.hashCode()== b.hashCode()
:!b.equals(a)&& a.compareTo(b)!= 0&&
a.compareTo(b)== -b.compareTo(a)
必须评估至真实
以满足相关合约。 因此 null
是不允许的,因为你不能这样做:
null.compareTo(a)
比较器
更灵活,因此处理 null
是一个特定于实现的问题。支持与否,取决于你希望你的
Comparator
做什么。
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?
Comparable
doesn't allow null
simply because:
a.compareTo(b) == -b.compareTo(a)
for all objects a
and b
where !a.equals(b)
. More specifically:
a.equals(b) ? b.equals(a) && a.compareTo(b) == 0 &&
b.compareTo(a) == 0 && a.hashCode() == b.hashCode()
: !b.equals(a) && a.compareTo(b) != 0 &&
a.compareTo(b) == -b.compareTo(a)
must evaluate to true
to satisfy the relevant contracts.
So null
isn't allowed because you can't do:
null.compareTo(a)
Comparator
is more flexible so handling of null
is an implementation-specific issue. Support it or not depending on what you want your Comparator
to do.
这篇关于Comparable和Comparator关于null的合同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!