Comparable
договор устанавливает, что e.compareTo(null)
должен бросить NullPointerException
.Договор со сравнительным и компаратором по отношению к нулю
От the API:
Обратите внимание, что
null
не является экземпляром какого-либо класса, иe.compareTo(null)
должен броситьNullPointerException
несмотря на то,e.equals(null)
возвращаетсяfalse
.
С другой стороны, Comparator
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
и метанииNullPointerException
? - Не стоит ли даже сортировать
List
, содержащийnull
элементов, или это верный признак ошибки дизайна?
Примечание для других, имеющих проблемы с компиляцией этого кода: есть ошибка в javac, но она компилируется и запускается в Eclipse !!! http://stackoverflow.com/questions/2858799/generics-compiles-and-runs-in-eclipse-but-doesnt-compile-in-javac – polygenelubricants