web-dev-qa-db-ja.com

標準APIには自然なコンパレータが存在しますか?

オブジェクトの自然な順序付けまたはカスタムの順序付けを使用できる戦略パターンの一部としてコンパレーターが必要です。自然順序付けの場合、単純なコンパレーターを作成しました。

private static class NaturalComparator<T extends Comparable<? super T>> implements Comparator<T> {
    @Override
    public int compare(T o1, T o2) {
        return o1.compareTo(o2);
    }
}

簡単そうに思えますが、標準APIの誰かを知っている人がいるかどうか疑問に思っていました。 TreeMapを見て、そのようなクラスなしでそれを行うので、そのコードが書かれたとき、明らかな答えはノーになりますが、おそらく後で追加されました。

54
Yishai

Comparator in Java 8 :に追加されました。

static <T extends Comparable<? super T>> Comparator<T> naturalOrder()

たとえば、次のように使用します。

Comparator<Double> natural = Comparator.<Double>naturalOrder();
return natural.compare(1.0, 1.1));
63
Julien

はい、JDKには間違いなくあります!ここにあります:

Collections.reverseOrder(Collections.reverseOrder())

冗談だ。 (しかし、それは本当です。(実際にそれを使用しないでください。(これまで)))

50

JDKにはありませんが、ComparableComparatorと呼ばれ、 Springなどの多くのフレームワークに存在しますApache CommonsHibernate など

10
Eugene Ryzhikov

クラスに自然な順序がある場合、Javaでは、各クラスにComparable実装を持たせるのではなく、Comparatorを実装するのがより一般的です。

したがって、問題のオブジェクトに自然順序付けが定義されている場合、Comparableを実装し、compareToメソッドを定義する必要があります。 Comparatorを探す必要はありません。 Java.utilのほとんどのクラスは、強制する特定の順序がある場合はオプションのComparatorを取るか、他の順序が指定されていない場合はオブジェクトでcompareToを呼び出します。

要するに、クラスに自然順序付けを課す場合は常にComparableを実装し、自然順序付け以外のものが必要な場合にのみComparatorを使用してください。

2
MAK

私はJavaのデフォルトのコンパレーターに慣れていませんが、明らかに、compareToのComparatorは多くの場合単なるラッパーです。

標準のAPIには一般的な「自然順序付け」はありませんが、数値などの特定の組み込み型にはcompareToの実装があり、それが自然順序付けになります。

TreeMapおよびTreeSetおよびこれらすべては、配置するオブジェクトがComparableを実装していない場合、RuntimeExceptionをスローする必要があります。したがって、たとえば、文字列または数字をスローできますが、別のコレクションはスローできません。

TreeMapのコードは、コンパレータが使用できない場合、コンパレータを使用しません-代わりにcompareToを使用します。 compareToを使用するには、例外のソースであるComparableにキャストします。

    private int compare(K k1, K k2) {
      return (comparator==null ? ((Comparable <K>)k1).compareTo(k2)
                                : comparator.compare((K)k1, (K)k2));
  }
2
Uri