Comparable and Comparator contract with regards to null
从API:
Note that
null is not an instance of any class, ande.compareTo(null) should throw aNullPointerException even thoughe.equals(null) returnsfalse .
另一方面,
1 2 3 4 5 6 7 8 9 10 | 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); } }; } |
这使我们可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 和丢弃NullPointerException 的不成文规则? - 对包含
null 元素的List 进行排序是一个好主意,还是这是设计错误的一个确定标志?
1 | a.compareTo(b) == -b.compareTo(a) |
对于所有对象
1 2 3 4 | 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) |
必须对
所以不允许使用
1 | null.compareTo(a) |
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?
从概念上讲,空意味着"没有",在列表中放置任何东西对我来说都是奇怪的。此外,Java列表约定声明
Some list implementations have restrictions on the elements that they may contain. For example, some implementations prohibit null elements
因此,甚至不需要支持Java元素来支持空元素。综上所述,如果您没有很好的理由将空值放入一个列表中,那么就不要这样做,如果这样做了,那么就测试它是否实际按预期工作。
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?
好吧,列表包含空对象可能没有意义,但是您的列表可能包含一个"业务对象",您可以根据业务对象的不同属性进行排序,其中一些属性可能包含空值。
Is this an acceptable use of a
Comparator
BeanComparator允许您对业务对象中的属性进行排序,即使该属性包含空值,所以我不得不说它是Comparator的一种可接受的用法。