compareTo()
このような単純なクラスのメソッドを実装しています ( Collections.sort()
Java プラットフォームによって提供されるその他の機能を使用できるようにするため):
public class Metadata implements Comparable<Metadata> {
private String name;
private String value;
// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}
これらのオブジェクトの自然な順序付けを次のようにしたいと考えています。1) 名前で並べ替え、2) 名前が同じ場合は値で並べ替えます。どちらの比較も大文字と小文字を区別しない必要があります。両方のフィールドで null 値は完全に許容されるためcompareTo
、これらのケースで壊れてはなりません。
頭に浮かぶ解決策は、次のようなものです (ここでは「ガード句」を使用していますが、他の人は単一のリターン ポイントを好むかもしれませんが、それは重要ではありません)。
// primarily by name, secondarily by value; null-safe; case-insensitive
public int compareTo(Metadata other) {
if (this.name == null && other.name != null){
return -1;
}
else if (this.name != null && other.name == null){
return 1;
}
else if (this.name != null && other.name != null) {
int result = this.name.compareToIgnoreCase(other.name);
if (result != 0){
return result;
}
}
if (this.value == null) {
return other.value == null ? 0 : -1;
}
if (other.value == null){
return 1;
}
return this.value.compareToIgnoreCase(other.value);
}
これでうまくいきますが、私はこのコードに完全に満足しているわけではありません。確かにそれほど複雑ではありませんが、非常に冗長で退屈です。
問題は、(機能を維持しながら)どのようにこれを冗長にしないかということです。役立つ場合は、Java 標準ライブラリまたは Apache Commons を自由に参照してください。これを(少し)簡単にする唯一のオプションは、独自の「NullSafeStringComparator」を実装し、それを両方のフィールドの比較に適用することでしょうか?
編集 1-3 : Eddie の権利。上記の「両方の名前が null」の場合を修正
採用された回答について
もちろん、2009年にJava 1.6でこの質問をしましたが、当時、Eddieによる純粋なJDKソリューションが私の好みの受け入れられた回答でした。私は今まで(2017年)それを変えようとはしませんでした。
2009 Apache Commons Collections のものと 2013 Guava のもので、どちらも私が投稿したサードパーティのライブラリ ソリューションもあります。
私は今、Lukasz Wiktor によるクリーンなJava 8 ソリューションを受け入れられた答えにしました。Java 8 を使用している場合は、これが確実に優先されます。最近では、ほぼすべてのプロジェクトで Java 8 を使用できるはずです。