Comparable和Comparator关于null的合同 [英] Comparable and Comparator contract with regards to null

查看:174
本文介绍了Comparable和Comparator关于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]




  • 这是 Comparator 的可接受用法,还是违反了关于比较 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, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false.

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 comparing null and throwing NullPointerException?
  • Is it ever a good idea to even have to sort a List containing null 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屋!

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