コンパレーター、コレクションのソート - 1

「こんにちは、アミーゴ!」

「こんにちは、ビラーボ!」

「今日は、小さいですが興味深く役立つトピック、コレクションの並べ替えについて検討します。」

「仕分け? それについて何か聞いたことがあります。」

「昔は、すべてのプログラマーはソート アルゴリズムを作成できなければなりませんでした。それは可能でしたし、そうしなければなりませんでした。しかし、そんな時代は終わりました。今日では、独自のソート コードを作成することは、すでに作成されている他のコードを書き直すのと同じように、悪い形式とみなされています。発明されました。」

「Java (および他のプログラミング言語) では、ソートはすでに実装されています。 あなたの課題は、既存のものを適切に使用する方法を学ぶことです。

"OK。"

コレクションヘルパー クラスには、コレクション (より正確にはリスト) を並べ替えるのに使用される静的並べ替えメソッドがあります。マップとセットの要素には順序やインデックスがないため、並べ替えるものはありません。」

「はい、覚えています。私は一度この方法を使って数字のリストを並べ替えました。」

「素晴らしいです。しかし、このメソッドは一見したよりもはるかに強力です。数値だけでなく、あらゆるオブジェクトを任意の基準に基づいて並べ替えることができます。メソッドがこれを行うのに役立つ 2 つのインターフェイス、 Comparable と Comparator があります

「数値ではなくオブジェクトを並べ替える必要がある場合があります。たとえば、人々のリストがあり、年齢順に並べ替えたいとします。このためのComparableインターフェイスがあります。」

「まず例を示しましょう。そうすればすべてがより明確になるでしょう。」

public class Woman implements Comparable<Woman>
{
public int age;

public Woman(int age) {
this.age = age;
}

public int compareTo(Woman o)
{
return this.age - o.age;
}
}
使用方法の例:
public static void main(String[] args )
{
ArrayList<Woman> women = new ArrayList<Woman>();
women.add(new Woman(18));
women.add(new Woman(21));
women.add(new Woman(5));

Collections.sort(women);
}

「オブジェクトを並べ替えるには、まず比較方法を知る必要があります。このために、Comparable を使用します。Comparable インターフェイスはジェネリックです。つまり、型引数を受け入れます。このインターフェイスには、compareTo(T o) という 1 つのジェネリック メソッドしかありません。このメソッドは、現在のオブジェクト (this) と引数として渡されたオブジェクト (o) を比較します。つまり、このメソッドをクラスに実装し、それを使用して現在のオブジェクト (this) と渡されたオブジェクトを比較する必要があります。 」

「そして、compareTo はどのように機能するのでしょうか? 渡されたオブジェクトが大きいか小さいかに応じて true または false を返すと予想していました。」

「ここでの処理はさらに複雑です。compareTo メソッドは true/false を返しません。代わりに int を返します。これは実際には簡単にするために行われます。」

「コンピュータは、ある数値が別の数値より大きいかどうかを判断する必要がある場合、単純に最初の数値から 2 番目の数値を引いて、その結果を調べます。結果が 0 であれば、それらの数値は等しいです。結果が 0 より小さい場合は、の場合、2 番目の数値の方が大きくなります。結果が 0 より大きい場合は、最初の数値の方が大きくなります。」

"同じロジックがここにも当てはまります。仕様によれば、比較されたオブジェクトが等しい場合、compareTo メソッドはゼロを返さなければなりません。compareTo メソッドがゼロより大きい数値を返した場合、私たちのオブジェクトは渡されたオブジェクトより大きいことになります。メソッドがゼロより小さい数値を返した場合、'this' は渡されたオブジェクトより小さいです。」

「それはちょっと変ですね。」

「はい、ただし、単純に数値プロパティに基づいてオブジェクトを比較している場合は、一方から他方を減算することでオブジェクト間の差を返すことができます。上記の例で行われた方法と同じです。」

public int compareTo(Woman o)
{
return this.age - o.age;
}

「すべてを理解していると思います。でも、おそらくそうではありません。しかし、ほとんどすべて。」

「素晴らしいです。では、より現実的な問題を考えてみましょう。中国で婦人服を作るためのクールな Web サイトを作成したとします。顧客を説明するために Woman クラスを使用します。すべての顧客を確認できる表を含む Web ページも作成しました。 . でも問題があるんです…」

「Woman オブジェクトには、年齢だけでなく、名前、姓、身長、体重、子供の数など、その他のデータも多数含まれています。」

「ユーザーのテーブルにはたくさんの列があります。ここで疑問があります。さまざまな基準でユーザーをどのように並べ替えますか? 体重順、年齢順、姓順?」

「うーん。そうですね、列でソートできる表をよく見かけます。それで、どうやってソートするのですか?」

"このために、今日説明したい 2 番目のインターフェイスである Comparator インターフェイスがあります。これにも Compare メソッドがありますが、引数は 1 つではなく 2 つとります: int Compare(T o1, T o2)。これがその方法です。作品:"

public class Woman
{
public int age;
public int childrenCount;
public int weight;
public int height;
public String name;

public Woman(int age) {
this.age = age;
}
}
使用方法の例:
public static void main(String[] args )
{
ArrayList<Woman> women = new ArrayList<Woman>();
women.add(new Woman(18));
women.add(new Woman(21));
women.add(new Woman(5));

Comparator<Woman> compareByHeight = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.height - o2.height;
}
};

Collections.sort(women, compareByHeight);
}

「Comparator インターフェイスは、比較対象のオブジェクトのクラス内にオブジェクト比較ロジックを隠しません。代わりに、別のクラスに実装されます。」

「それでは、Comparator インターフェイスを実装するいくつかのクラスを作成し、それぞれのクラスで異なるプロパティを比較させることができます。1 つは体重、もう 1 つは年齢、3 つ目は身長でしょうか?」

「はい、とても簡単で便利です。」

「 Collections.sortメソッドを呼び出して、オブジェクトのリストと別の特別なオブジェクトを 2 番目の引数として渡すだけです。これはComparatorインターフェイスを実装し、並べ替えプロセスでオブジェクトのペアを正しく比較する方法を示します。」

「うーん。すべて理解できたと思います。試してみましょう。ユーザーを重みで並べ替える必要があるとします。次のようになります。」

ユーザーを重みで並べ替える例:
Comparator<Woman> compareByWeight = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.weight - o2.weight;
}
};

Collections.sort(women, compareByWeight);

"はい、正確に。"

「すごいですね。でも、逆順に並べ替えたい場合はどうすればいいでしょうか?」

「考えてみてください。答えはとても簡単です!」

「分かりました!こんな感じです。」

昇順で並べ替えます:
return o1.weight - o2.weight;
降順で並べ替えます:
return o2.weight – o1.weight;

「そうだね。よくやった」

「それで、姓で並べ替えたい場合はどうすればいいですか? 文字列を並べ替えるにはどうすればいいですか、ビラーボ?」

「String クラスには、compareTo メソッドがすでに実装されています。必要なのは、それを呼び出すだけです。」

ユーザーを名前で並べ替える例:
Comparator<Woman> compareByName = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.name.compareTo(o2.name);
}
};

Collections.sort(women, compareByName);

「素晴らしい教訓でした、ビラーボ。ありがとうございました。」

「そして、友人よ、あなたに感謝します!」