高度なソート技術
実際のアプリケーションでは、より複雑なソートロジックが必要になることがよくあります。例えば以下のようなものです。
- 複数の基準でソートする(例:GPA でソートし、GPA が同じ場合は名前でソートする)
- 逆順でソートする
- カスタムのコンパレータチェーンを作成する
これらの高度な技術を探ってみましょう。
複数の基準でソートする
~/project ディレクトリに MultiCriteriaDemo.java という名前の新しいファイルを作成します。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class MultiCriteriaDemo {
public static void main(String[] args) {
// Create a list of students with some having the same GPA
List<Student> students = new ArrayList<>();
students.add(new Student("John", 3.5, 101));
students.add(new Student("Mary", 3.8, 102));
students.add(new Student("Alice", 3.5, 103)); // Same GPA as John
students.add(new Student("Bob", 3.8, 104)); // Same GPA as Mary
students.add(new Student("Charlie", 3.2, 105));
// Print the unsorted list
System.out.println("Unsorted Student List:");
for (Student student : students) {
System.out.println(student);
}
// Sort first by GPA, then by name
Comparator<Student> byGpa = Comparator.comparing(Student::getGpa);
Comparator<Student> byName = Comparator.comparing(Student::getName);
// Combine the comparators using thenComparing
Comparator<Student> byGpaThenName = byGpa.thenComparing(byName);
// Sort the list
Collections.sort(students, byGpaThenName);
// Print the sorted list
System.out.println("\nStudents sorted by GPA, then by name:");
for (Student student : students) {
System.out.println(student);
}
}
}
このプログラムは以下のことを行います。
-
一部の学生が同じ GPA を持つ学生リストを作成します。
-
GPA 用のコンパレータと名前用のコンパレータを作成します。
-
thenComparing() メソッドを使用してこれらのコンパレータを結合します。
-
学生をまず GPA でソートし、GPA が同じ場合は名前でソートします。
-
コードをコンパイルして実行します。
cd ~/project
javac Student.java MultiCriteriaDemo.java
java MultiCriteriaDemo
以下のような出力が表示されるはずです。
Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
Bob, GPA: 3.8, Reg No: 104
Charlie, GPA: 3.2, Reg No: 105
Students sorted by GPA, then by name:
Charlie, GPA: 3.2, Reg No: 105
Alice, GPA: 3.5, Reg No: 103
John, GPA: 3.5, Reg No: 101
Bob, GPA: 3.8, Reg No: 104
Mary, GPA: 3.8, Reg No: 102
同じ GPA を持つ学生(3.5 の Alice と John、3.8 の Bob と Mary)がアルファベット順にソートされていることに注意してください。
逆順でソートする
~/project ディレクトリに ReverseOrderDemo.java という名前の新しいファイルを作成します。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ReverseOrderDemo {
public static void main(String[] args) {
// Create a list of students
List<Student> students = new ArrayList<>();
students.add(new Student("John", 3.5, 101));
students.add(new Student("Mary", 3.8, 102));
students.add(new Student("Alice", 3.2, 103));
students.add(new Student("Bob", 3.9, 104));
students.add(new Student("Charlie", 3.0, 105));
// Print the unsorted list
System.out.println("Unsorted Student List:");
for (Student student : students) {
System.out.println(student);
}
// Method 1: Using Collections.reverseOrder() with a comparator
Comparator<Student> byGpa = Comparator.comparing(Student::getGpa);
Comparator<Student> byGpaReversed = Collections.reverseOrder(byGpa);
Collections.sort(students, byGpaReversed);
System.out.println("\nStudents sorted by GPA in descending order (Method 1):");
for (Student student : students) {
System.out.println(student);
}
// Method 2: Using the reversed() method of Comparator
Collections.sort(students, Comparator.comparing(Student::getName).reversed());
System.out.println("\nStudents sorted by name in reverse alphabetical order (Method 2):");
for (Student student : students) {
System.out.println(student);
}
}
}
このプログラムは逆順でソートする 2 つの方法を示しています。
-
Collections.reverseOrder() を使用してコンパレータを逆にする
-
コンパレータの reversed() メソッドを使用する
-
コードをコンパイルして実行します。
cd ~/project
javac Student.java ReverseOrderDemo.java
java ReverseOrderDemo
以下のような出力が表示されるはずです。
Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104
Charlie, GPA: 3.0, Reg No: 105
Students sorted by GPA in descending order (Method 1):
Bob, GPA: 3.9, Reg No: 104
Mary, GPA: 3.8, Reg No: 102
John, GPA: 3.5, Reg No: 101
Alice, GPA: 3.2, Reg No: 103
Charlie, GPA: 3.0, Reg No: 105
Students sorted by name in reverse alphabetical order (Method 2):
Mary, GPA: 3.8, Reg No: 102
John, GPA: 3.5, Reg No: 101
Charlie, GPA: 3.0, Reg No: 105
Bob, GPA: 3.9, Reg No: 104
Alice, GPA: 3.2, Reg No: 103
最初のソートでは学生が GPA の降順で表示され、2 番目のソートでは学生が名前の逆アルファベット順で表示されます。
複雑なソートチェーン
- 複数の基準と逆順ソートを組み合わせたもう 1 つの例を作成しましょう。
~/project ディレクトリに ComplexSortingDemo.java という名前のファイルを作成します。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComplexSortingDemo {
public static void main(String[] args) {
// Create a list of students with varied data
List<Student> students = new ArrayList<>();
students.add(new Student("John", 3.5, 101));
students.add(new Student("Mary", 3.8, 102));
students.add(new Student("Alice", 3.5, 103)); // Same GPA as John
students.add(new Student("Bob", 3.8, 104)); // Same GPA as Mary
students.add(new Student("Charlie", 3.2, 105));
students.add(new Student("David", 3.2, 106)); // Same GPA as Charlie
// Print the unsorted list
System.out.println("Unsorted Student List:");
for (Student student : students) {
System.out.println(student);
}
// Create a complex sorting chain:
// 1. Sort by GPA in descending order
// 2. If GPAs are equal, sort by name in ascending order
// 3. If names are also equal, sort by registration number in descending order
Comparator<Student> complexComparator = Comparator
.comparing(Student::getGpa, Comparator.reverseOrder())
.thenComparing(Student::getName)
.thenComparing(Student::getRegNo, Comparator.reverseOrder());
Collections.sort(students, complexComparator);
System.out.println("\nStudents sorted by complex criteria:");
System.out.println("(GPA descending, then name ascending, then reg. number descending)");
for (Student student : students) {
System.out.println(student);
}
}
}
このプログラムは以下のような複雑なソートチェーンを作成します。
-
まず学生を GPA の降順でソートします。
-
GPA が同じ場合は、名前の昇順でソートします。
-
GPA と名前の両方が同じ場合は、登録番号の降順でソートします。
-
コードをコンパイルして実行します。
cd ~/project
javac Student.java ComplexSortingDemo.java
java ComplexSortingDemo
以下のような出力が表示されるはずです。
Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
Bob, GPA: 3.8, Reg No: 104
Charlie, GPA: 3.2, Reg No: 105
David, GPA: 3.2, Reg No: 106
Students sorted by complex criteria:
(GPA descending, then name ascending, then reg. number descending)
Bob, GPA: 3.8, Reg No: 104
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
John, GPA: 3.5, Reg No: 101
Charlie, GPA: 3.2, Reg No: 105
David, GPA: 3.2, Reg No: 106
この出力では:
- Bob と Mary はどちらも GPA が 3.8 ですが、アルファベット順で Bob が先に来ます。
- Alice と John はどちらも GPA が 3.5 ですが、アルファベット順で Alice が先に来ます。
- Charlie と David はどちらも GPA が 3.2 ですが、アルファベット順で Charlie が先に来ます。
これは、コンパレータをチェーンすることで複雑な多段階のソートロジックを作成できることを示しています。