この記事は、クリーン コードの原則に関する無料の Java 8 コースの一部です。
この記事では、Java Comparableインターフェースについて説明します。
良いビデオもありますので、ここをクリックしてください。
物事をどのように比較して順序付けすればよいですか?この質問は少しわかりにくいかもしれませんが、真剣に考えていただければ幸いです。たとえば、リンゴのグループがあります:
例 1
どうやってそれらを分類しますか?重量順に並べ替えますか?もしそうなら、それらは最も軽いものから最も重いものへ、または最も重いものから最も軽いものへソートされていますか?リンゴを選別するときは、すべてのリンゴが正しく選別されるまで、2 つのリンゴの重さを繰り返し比較する必要があります。 Apple 1 は Apple 2 より重いですか?ということはiPhone 3よりも重いのでしょうか?分類が完了するまで比較を続ける必要があります。 Comparable インターフェイスは、この目標を達成するのに役立ちます。 Comparable 自体は オブジェクト をソートできませんが、インターフェースによって定義されたメソッド int CompareTo(T) はソートできます。
まずは、compareTo() メソッドを使用してどのリンゴが重いかを見てみましょう。
例 2
compareTo() メソッドは、正、負、またはゼロの int 値を返すことによって機能します。オブジェクトを引数として呼び出してオブジェクトを比較します。負の数値は、呼び出されるオブジェクトが引数よりも「軽い」ことを示します。リンゴを大きさで比較する場合、赤いリンゴは緑のリンゴよりも小さいため、上記の呼び出しでは -400 などの負の数が返されます。 2 つのリンゴの重さが同じ場合、呼び出しは 0 を返します。赤いリンゴの方が重い場合、compareTo() は 68 などの正の数を返します。
上記の CompareTo() メソッドを繰り返し呼び出すと、サイズで並べ替えることができます。これは素晴らしいことですが、これで終わりではありません。リンゴを色別に分類したい場合はどうすればよいでしょうか?それとも体重ですか?私たちにもできます。重要なのは、私たちのクライアント - 彼を Fat Farmer と呼びましょう (例 3 を参照) - 開発を開始する前に、リンゴをどのように分類する必要があるかを正確に定義する必要があるということです。
例 3
彼は次の 2 つの質問に答えることでこれを行うことができます:
リンゴをどのように分類したいですか?彼はどのような特徴を私たちに比較してほしいと考えていますか?
その文脈では、「未満」、「等しい」、「より大きい」とは何を意味しますか?
複数の機能を使用することもできます。これについては後ほど説明します。
この最初の例では、リンゴを重量で並べ替えます。必要なのは 1 行のコードだけです。
Collections.sort(apples);
例 4
リンゴの並べ替え方法を事前に定義している限り、上記のコード行ですべての並べ替え作業を行うことができます (これには複数行のコードが必要です)。
リンゴのカテゴリを書き始めましょう。
public class Apple implements Comparable { private String variety; private Color color; private int weight; @Override public int compareTo(Apple other) { if (this.weight < other.weight) { return -1; } if (this.weight == other.weight) { return 0; } return 1; } }
例 5
これは、Apple クラスの最初のバージョンです。 CompareTo メソッドを使用してリンゴを並べ替えているため、Comparable インターフェイスを実装しました。この最初のバージョンでは、オブジェクトを重量で比較します。 CompareTo() メソッドでは、このリンゴの重さが他のリンゴよりも軽い場合、負の数が返されるという if 条件を作成します。単純にするために、それが -1 であると仮定します。これは、この Apple が「他の Apple」よりも軽いことを意味することを忘れないでください。 2 番目の if ステートメントでは、リンゴの重さが等しい場合に 0 が返されることを示しています。もちろん、このリンゴが軽くなく、同じくらい重くない場合は、他のリンゴよりも重いだけです。この場合、1 と仮定して正の数を返します。
正如我前面提到的,我们还可以使用compareTo()比较多个特征。比方说,我们第一通过品种排序苹果,但如果两个苹果是同一品种,那么我们就按颜色排序。最后,如果这两个特性相同,那么我们将按重量排序。虽然我们可以手动实现这件事,就像我在最后一个例子中做的那样,但是其实可以用一种简洁得多的方式实现。一般来说,最好是重用现有的代码,而不是自己写。我们可以在Integer、String和枚举类中使用compareTo方法来比较值。由于我们没有使用Integer对象,用了int,所以我们不得不使用来自于Integer包装器类的一个静态的helper方法来比较两个值。
public class Apple implements Comparable { private String variety; private Color color; private int weight; @Override public int compareTo(Apple other) { int result = this.variety.compareTo(other.variety); if (result != 0) { return result; } if (result == 0) { result = this.color.compareTo(other.color); } if (result != 0) { return result; } if (result == 0) { result = Integer.compare(this.weight, other.weight); } return result; } }
例6
在例6中,我们比较了客户指定的苹果的第一特性,它们的品种。如果compareTo()调用的结果为非零,那么我们返回值。否则,我们调用另一个compareTo()直到得到一个非零值,或者直到已经比较完这三个特征。尽管此代码可以工作,但它不是最有效或干净的解决方案。在例3中,我们重构我们的代码,使其更简单。
@Override public int compareTo(Apple other) { int result = this.variety.compareTo(other.variety); if (result == 0) { result = this.color.compareTo(other.color); } if (result == 0) { result = Integer.compare(this.weight, other.weight); } return result; }
例7
正如你所看到的,这大大减少了代码,并且每一次比较只要一行代码。如果一个compareTo()调用的结果是零,那么我们就转移到下一个相同if语句的比较中。顺便说一句,这是成为Clean Coder的一个很好的例子。通常情况下,你不需要立即写出干净的代码;你可以从一个粗略的想法开始,使其可以工作,然后不断改进,直到你尽可能得让它干净就可以了。
你可能会注意到compareTo()看起来有点像hashCode()和equals()方法。但是,它们有一个重要的区别。对于hashCode()和equals()方法,比较个体属性的顺序不影响返回的值,但是,在compareTo()中,通过你比较对象的顺序来定义对象的顺序。
在结论中我只想强调Comparable接口是多么的重要。它既用于java.util.Arrays,也用于java.util.Collections实用程序类,来排序元素和搜索排序集合中的元素。使用TreeSet和Tree Map,就更简单了——想要它们会自动排序必须实现Comparable接口的元素。
以上がJava Comparableインターフェースのサンプルコードの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。