36

Comparable契約は、e.compareTo(null)をスローする必要があることを指定しますNullPointerException

APIから:

nullはどのクラスのインスタンスでもないため、 を返してもe.compareTo(null)をスローする必要があることに注意してください。NullPointerExceptione.equals(null)false

一方、ComparatorAPIは、比較時に何が起こる必要があるかについては何も言及していませんnull。を受け取り、最小要素としてput をComparable返すジェネリック メソッドの次の試行を検討してください。Comparatornull

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に関する不文律に違反していますか?nullNullPointerException
  • List含まれている要素を並べ替える必要さえあるのは良い考えnullですか、それとも設計エラーの確かな兆候ですか?
4

3 に答える 3

25

Comparable許可しないnull理由は次のとおりです。

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

すべてのオブジェクト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)

true関連する契約を満たすために評価する必要があります。

nullのことができないため、許可されていません。

null.compareTo(a)

Comparatorはより柔軟であるため、の処理はnull実装固有の問題です。あなたが何をしたいかによって、それをサポートするかしないかを決めてComparatorください。

于 2010-05-18T15:28:44.107 に答える
8

null 要素を含む List を並べ替える必要さえあるのは良い考えですか、それとも設計エラーの確かな兆候ですか?

概念的には、null は「何もない」ことを意味し、リストに何も配置しないのは奇妙に思えます。また、Java List コントラクトには次のように記載されています。

一部のリストの実装には、含まれる要素に制限があります。たとえば、一部の実装では null 要素が禁止されています

そのため、Java での List 実装は、null 要素をサポートする必要さえありません。要約すると、null をリストに入れる正当な理由がない場合は、入れないでください。入れた場合は、実際に期待どおりに動作することをテストしてください。

于 2010-05-18T15:31:12.790 に答える
4

null 要素を含む List を並べ替える必要さえあるのは良い考えですか、それとも設計エラーの確かな兆候ですか?

おそらく、リストに null オブジェクトが含まれていても意味がありませんが、リストに「ビジネス オブジェクト」が含まれている可能性があり、ビジネス オブジェクトのさまざまなプロパティで並べ替えることができます。その中には null が含まれているものもあります。

これはコンパレータの許容可能な使用法ですか?

BeanComparatorを使用すると、プロパティに null が含まれている場合でも、ビジネス オブジェクト内のプロパティで並べ替えることができるため、Comparator の許容可能な使用法であると言わざるを得ません。

于 2010-05-18T16:35:19.657 に答える