java 关于 null 的 Comparable 和 Comparator 合同

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2858628/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 23:11:08  来源:igfitidea点击:

Comparable and Comparator contract with regards to null

javagenericsnullcomparatorcomparable

提问by polygenelubricants

Comparablecontract specifies that e.compareTo(null)must throw NullPointerException.

Comparable合同指定e.compareTo(null)必须抛出NullPointerException

From the API:

API

Note that nullis not an instance of any class, and e.compareTo(null)should throw a NullPointerExceptioneven though e.equals(null)returns false.

请注意,null它不是任何类的实例,即使返回也e.compareTo(null)应该抛出一个。NullPointerExceptione.equals(null)false

On the other hand, ComparatorAPImentions nothing about what needs to happen when comparing null. Consider the following attempt of a generic method that takes a Comparable, and return a Comparatorfor it that puts nullas the minimum element.

另一方面,ComparatorAPI没有提到在比较null. 考虑以下泛型方法的尝试,该方法采用 a Comparable,并Comparator为其返回 anull作为最小元素。

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 nulland throwing NullPointerException?
  • Is it ever a good idea to even have to sort a Listcontaining nullelements, or is that a sure sign of a design error?
  • 这是可以接受的 a 用法Comparator,还是违反了关于比较null和抛出的不成文规则NullPointerException
  • 甚至必须对List包含的null元素进行排序是否是一个好主意,或者这是否是设计错误的明确迹象?

回答by cletus

Comparabledoesn't allow nullsimply because:

Comparable不允许null仅仅因为:

a.compareTo(b) == -b.compareTo(a)

for all objects aand bwhere !a.equals(b). More specifically:

对于所有对象abwhere !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)

must evaluate to trueto satisfy the relevant contracts.

必须评估以true满足相关合同。

So nullisn't allowed because you can't do:

所以null是不允许的,因为你不能这样做:

null.compareTo(a)

Comparatoris more flexible so handling of nullis an implementation-specific issue. Support it or not depending on what you want your Comparatorto do.

Comparator更灵活,因此处理null是特定于实现的问题。支持与否取决于您想要Comparator做什么。

回答by Anno v. Heimburg

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?

甚至必须对包含空元素的 List 进行排序是否是一个好主意,或者这是否是设计错误的明确迹象?

Conceptually, null means "nothing", and placing nothing in a list seems weird to me. Also, the Java List contract states that

从概念上讲,null 意味着“没有”,在我看来,在列表中什么都不放似乎很奇怪。此外,Java List 合同规定

Some list implementations have restrictions on the elements that they may contain. For example, some implementations prohibit null elements

一些列表实现对它们可能包含的元素有限制。例如,某些实现禁止空元素

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.

所以 Java 中的 List 实现根本不需要支持空元素。总而言之,如果您没有充分的理由将 null 放入列表中,请不要,如果您这样做了,请测试它是否真的按预期工作。

回答by camickr

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?

甚至必须对包含空元素的 List 进行排序是否是一个好主意,或者这是否是设计错误的明确迹象?

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.

好吧,列表包含空对象可能没有意义,但也许您的列表包含“业务对象”,您可以对业务对象的不同属性进行排序,其中一些可能包含空值。

Is this an acceptable use of a Comparator

这是比较器的可接受用法吗

The BeanComparatorallows 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.

BeanComparator允许你在一个业务对象属性格式进行排序,即使属性包含空值,所以我不得不说这是一个比较可以接受的使用。