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
}
私が欲しい自然順序付け名前が同じである場合の値でソート)の名前と2でソート)1;:これらのオブジェクトのためにあることを どちらの比較でも、大文字と小文字は区別されません。どちらのフィールドでも、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:エディの権利。上記の「両方の名前がnullである」ケースを修正
採用された回答について
私は2009年にJava 1.6でこの質問をしましたが、当時はEddieによる純粋なJDKソリューションが私の好まれた回答でした。今まで(2017年)までそれを変えることに慣れなかった。
サードパーティのライブラリソリューションもあります。2009年のApache Commons Collectionsと2013年のGuavaの2つで、どちらも私が投稿したものです。ある時点で私はそれを好みました。
私は今、Lukasz WiktorによるクリーンなJava 8ソリューションを受け入れられた答えにしました。Java 8を使用している場合は、これが間違いなく推奨され、最近では、ほとんどすべてのプロジェクトでJava 8を使用できます。