序文
挿入ソート、ヒルソート、マージソートなどのアルゴリズムを実行するときに、2つのオブジェクトの「サイズ」を比較する比較操作を指す場合。整数i> jの比較方法を理解するのは簡単ですが、複数のオブジェクトをソートすると、2つのオブジェクトの「サイズ」をどのように比較しますか? STU1> STU2のこのような比較は、明らかにコンパイルすることは不可能です。 2つのオブジェクトのサイズを比較する方法の問題を解決するために、JDKは2つのインターフェイスを提供しますjava.lang.Comparableとjava.util.Comparator提供します。
1。自然なソート:java.lang.comParable
比較可能なインターフェイスに提供されるメソッドは1つだけです。 compareTo(Object obj) 、およびこのメソッドの返品値はintです。戻り値が正の数字の場合、現在のオブジェクト(メソッドを呼び出すオブジェクト)がOBJオブジェクトよりも「大きい」ことを意味します。そうでなければ、それは「小」です。ゼロの場合、2つのオブジェクトが等しいことを意味します。
これは、同等のインターフェイスを実装する学生クラスです。
パブリッククラスの学生は同等の{private int id;プライベート文字列名; public Student(){super(); } @override public int compareto(object obj){if(obj instanceof sudent){sudine stu =(desute)obj; IDを返す-Stu.id; } return 0; } @Override public String toString(){return "<" + id + "、" + name + ">"; }}学生は、同等の自然なソートインターフェイスを実装します。では、このインターフェイスを使用して、学生オブジェクトのセットを並べ替えるにはどうすればよいですか?アレイを学習していたとき、クラスを使用して整数配列java.util.Arraysをソートしました。アレイのソートメソッドを使用して、整数配列をソートします。 APIドキュメントをめくった後、配列はsort(Object[] obj)を含むソートメソッドの多くの過負荷形式を提供することがわかります。ソートプロセス中に2つのオブジェクトの「サイズ」を比較する場合、比較可能なインターフェイスを使用して比較方法を比較します。
public class comparetest {public static void main(string [] args){desute stu1 = new Student(1、 "Little");学生stu2 = new Student(2、 "Cyntin");学生stu3 = new Student(3、 "Tony");学生stu4 = new Student(4、 "gemini");学生[] stus = new Student [4]; stu0] = stu1; stu1 [1] = stu4; stus [2] = stu3; stu3] = stu2; system.out.println( "array:" + arrays.toString(stus)); arrays.sort(stus); system.out.println( "sort:" + arrays.toString(stus)); }}学生アレイに要素が追加される順序は、学生IDに従って追加されません。 Arrays.sort(stus)を呼び出した後、生徒の配列を並べ替えます。どのソートアルゴリズムがそれを実装するために使用されていても、2つのオブジェクトの「サイズ」操作を比較することは間違いなく必要です。では、2つのオブジェクトの「サイズ」をどのように比較しますか?学生によって実装された同等のインターフェイスが登場します。 sortメソッドは、比較することと比較してオブジェクトをキャストし、比較メソッドを呼び出して、その2つのオブジェクトの「サイズ」を返す値に基づいて判断します。したがって、この例では、ソートされた元の学生のオーバーアウトアレイは、学生番号でソートされた学生配列になります。
しかし、ソートアルゴリズムが学生クラスにバインドされていることに気付き、学生にはソートアルゴリズムが1つしかないことがわかりました。しかし、これは本当の社会ではそうではありません。学生番号でソートしたくない場合はどうなりますか?名前で生徒を並べ替えたい場合はどうなりますか?学生クラスの比較可能なインターフェイスの比較方法を変更し、名前でソートするように変更することのみができます。同じシステムに2つの操作がある場合、1つは学生番号でソートされ、もう1つは名前でソートされた場合はどうなりますか?学生クラスの本体に2つのComparetoメソッドの実装を記述することは不可能です。この観点から、比較可能には制限があります。この欠点を補うために、JDKは別の並べ替え方法も提供します。これは、以下で説明します。
2。コンパレータ選別:java.util.comparator
Comparator Sorting Interfaceが提供される理由は、同じオブジェクトをさまざまな方法でソートする必要があり、この自然なソートを比較可能なものとして実装できないことがあるため、上記で述べました。さらに、コンパレータインターフェイスの利点の1つは、比較ソートアルゴリズムを特定のエンティティクラスと分離することです。
API sort(T[] a, Comparator<? super T> c)覗くと、オーバーロードされた形式の配列があることがわかります。この方法では、ジェネリックを使用してこの方法のパラメーターを記述していますが、これについてはまだ言及していません。この形式として理解できます。 sort(Object[] a, Comparator c) 。これは、比較並べ替えアルゴリズムに従ってオブジェクト配列をソートすることを意味します。コンパレータインターフェイスには2つの方法が定義されています。 compare(Object o1, Object o2)とメソッドequals 。 equalsメソッドにはすべてのオブジェクトのメソッドがあるため、Comparator Interfaceを実装するときは、 equalsメソッドをオーバーライドするのではなく、 compare方法をオーバーライドするだけです。 Comparator Interfaceのオーバーライドの説明は次のとおりです。「 Object.equals(Object)メソッドをオーバーライドしないことは常に安全であることに注意してください。ただし、場合によっては、このメソッドをオーバーライドすると、プログラムが2つの異なるコンパレータが同じソーティングを強制し、パフォーマンスを改善するかどうかを判断できます。」最初の文を知る必要があり、大丈夫です。つまり、Equalsメソッドの実装が表示されない場合でも、オブジェクトクラスのequalsメソッドを使用しても、コードは安全であるため、Equalsメソッドを実装する方法について考える必要はありません。
それでは、コンパレータでそれを並べ替えるためのコードを書いてみましょう。まだ学生クラスで行われていますが、同等のインターフェイスは実装されていません。コンパレータ実装クラスはディスプレイを使用して1つのメソッドのみを実装するため、クラスを作成するために作成する必要はありません。コンパレータを使用する必要がある場合は、匿名の内部クラスを作成してコンパレータを実装できます。
次に、名前で並べ替える方法です。
public void sortbyname(){学生stu1 = new Student(1、 "Little");学生stu2 = new Student(2、 "Cyntin");学生stu3 = new Student(3、 "Tony");学生stu4 = new Student(4、 "gemini");学生[] stus = new Student [4]; stu0] = stu1; stu1; stu4; stu2] = stu3; stu3] = stu2; system.out.println( "array:" + arrays.toString(stus)); arrays.sort(stus、new Comparator(){@Override public int Compare(Object o1、object o2){if(o1 Instanceof Student && o2 Instance of Student){学生S1 =(学生)O1;学生S2 =(学生)O2; // return S1.getid(); s1.getname()。比較(s2.getname()); system.out.println( "sorted:" + arrays.toString(stus)); }学生番号ごとに学生を並べ替える必要がある場合、学生クラスを変更せずに、ソートメソッドのコンパレータを実装する内部クラスのコードを変更するだけです。
注:もちろん、学生クラスを使用してコンパレータインターフェイスを実装することもできます。この種類を使用する必要がある場合は、学生をコンパレータとして使用してください。学生はコンパレータであるため、学生をソートメソッドにパラメーターとして渡すことができます。しかし、そのようなコードは優れたコードではありません。なぜなら、コンパレータを使用する重要な理由の1つは、比較アルゴリズムを特定のクラスから分離し、クラス間の結合を減らすことができるからです。
Treesetは、ツリーセットの2つのコンストラクターメソッドに対応する両方の比較方法をサポートしています。
1.TREESET():Treesetの要素によって実装された比較可能なインターフェイスの比較方法に従って比較とソート
2。ツリーセット(コンパレータコンパレータ):指定された比較コンパレータに従ってツリーセットの比較とソート要素
ツリーセットに要素を追加すると、ツリーセットは要素をソートします。自然な秩序であるかコンパレータで並べ替えるかについては、ツリーセットの構造がどのように書かれているかに依存します。もちろん、最初の要素を追加するときに比較はありません。ツリーセットには要素はありません。誰と比較できますか?
以下では、2つの並べ替えと比較方法を使用したツリーセットテストコードを示します。
/ ***自然sortの使用*学生は比較可能なインターフェイスを実装する必要があります。それ以外の場合は、ClassCastExceptionがスローされます*/ public void testSortedset3(){sudint stu1 = new Student(1、 "Little");学生stu2 = new Student(2、 "Cyntin");学生stu3 = new Student(3、 "Tony");学生stu4 = new Student(4、 "gemini"); sortedset set = new Treeset(); set.add(stu1); set.add(stu3); //学生が同等のインターフェイスを実装していない場合は、ClassCastException set.Add(STU4)をスローします。 set.add(stu2); set.add(stu4); set.add(新しい学生(12、 "Little")); System.out.println(set); } / ***並べ替えにコンパレータを使用する*学生は、比較可能なインターフェイスを実装せずに単純なJavaクラスにすることができます*/ public void testSortedset3(){sudint stu1 = new Student(1、 "Little");学生stu2 = new Student(2、 "Cyntin");学生stu3 = new Student(3、 "Tony");学生stu4 = new Student(4、 "gemini"); sortedset set = new Treeset(new Comparator(){@Override public int Compare(Object o1、object o2){if(o1 Instanceof Student && o2 instanceof student){desute s1 =(desute)o1; desute s2 =(desute)o2; return s1.getname()。比較()。 set.add(stu1); set.add(stu3); set.add(stu4); set.add(stu2); set.add(stu4); set.add(新しい学生(12、 "Little")); System.out.println(set); }さらに、ツールクラスjava.util.Collectionsを紹介します。これはコレクションインターフェイスではないことに注意してください。コレクションは、アレイクラスに非常に似ています。配列は、配列操作のための一連の静的メソッド、ソートなどを提供します。コレクションは一連のこのような方法も提供しますが、コレクションの処理に使用されます。コレクションクラスはコレクションインターフェイスに非常に似ていますが、コレクションの名前にだまされないでください。コレクションインターフェイスとサブインターフェイスのみを処理できる実装クラスではなく、マップインターフェイスの実装クラスも処理できます。
要約します
これは、Javaでの自然な並べ替えとコンパレーターの並べ替えの紹介の終わりです。この記事はまだ比較的詳細です。私はそれがあなたの勉強や仕事であなたを助けることができることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。