2012-04-04 15 views
3

最近、並べ替えアルゴリズムとさまざまな種類の入力との関係を理解するために取り組んでいます。現在、私は各学生が姓、GPA、ユーザーID(String、double、int)の3つのパラメータを持つStudent Managementプログラムに取り組んでいます。それらはそれぞれ3つのパラメータを持つStudentクラスに格納され、学生のDOZENSがあります(プログラムの主な機能は学生の入力、削除、更新です)。Java複数のパラメータを持つオブジェクトの並べ替え

私の質問は、主要なソートアルゴリズム(mergesort、quicksortなど)を使用して、各パラメータで学生のリストを並べ替える最も良い方法は何ですか?たとえば、mergesortを実行してGPAでリストをソートする最良の方法は何ですか?クイックソートを使ってリストを姓でソートするには?

本質的に私の質問は...私はこれらのオブジェクトを並べ替えることができます。3つのパラメータを持たない場合は(100の数値をソートするためのmergesortを書くのはとても簡単です)。他の2つのパラメータをどのように管理し、並べ替え後にアクセスできるかどうかを確認するにはどうすればよいですか?

+0

はこの宿題ですか? –

+0

宿題の割当(期限前)は、mergesortをハードコードして100個の整数のリストをソートする方法を学ぶことでした。私はもっ​​と大きなプロジェクトで作業を始めるときのためのJavaツールの限界を学ばそうとしています。 – MattDavBen

答えて

5

これがJavaで行われる方法は、別のComparatorsを使用することです。そして、あなたが言う:

Collections.sort(list, new NameComparator()); 

それとも

Collections.sort(list, new GpaComparator()); 

これらのコンパレータは、2つの要素間の順序を定義するために異なるフィールドを使用しています。

class NameComparator implements Comparator< Student> { 
    @Override public int compare(Student left, Student right) { 
     return left.getName().compareTo(right.getName()); 
    } 
} 

そしてGpaComparatorは、これはおそらくオフトピックですが、クールな何かを試してみたい場合は、JDK 8 Lambda Previewはいくつかを提供しています

class GpaComparator implements Comparator< Student> { 
    @Override public int compare(Student left, Student right) { 
     if (left.getGpa() < right.getGpa()) { 
      return -1; 
     } else if (left.getGpa() > right.getGpa()) { 
      return 1; 
     } else { 
      return 0; 
    } 
} 
+0

明確にしますGPAComparatorを書くより良い方法は、プリミティブの代わりに 'Integer'オブジェクトを使い、' .compare() 'メソッドに委譲することです。その後、 'if/elseif/else'ブロックが1行になります。 –

0

この場合、「数字」はユーザーの3つのフィールドであり、各桁の値は各フィールドの値によって制約され、フィールドの順序によって数値が決定されます。並べ替えの順位

もう少し具体的には、3つのフィールド(<GPA, Last Name, User ID>)を持つタプルがあり、GPA、姓、およびユーザーIDで並べ替えると仮定できます。 219は(すなわち、「何百」桁が「十」の数字が低いにも関わらず高い値を有する)139の上方にソートされる「GPAので、<3.75, Jones, 5>ようなタプルが<3.0, Adams, 2>上にソートされるのと同様に

(例えば、ジョーンズがアダムスより「低い」など)「桁数字」がより低い場合であっても、「数字」(より重要である)はより高い値を有する。

1

私はこの

public class Student implements Comparable { 
    public int compareType; //you can make this an enum if you want 
    ... 

    public int compareTo(Object o) { 
     if(compareType == 0) 
     return gpaCompareTo(o); 
     else if(compareType == 1) 
     return nameCompareTo(o); 

     return idCompateTo(o); 
    } 

    public int gpaCompareTo(Object o) { 
     //implement your gpaCompareTo 
    } 

    public int nameCompareTo(Object o) { 
     //implement your nameCompareTo 
    } 

    public int idCompareTo(Object o) { 
     //implement your idCompareTo 
    } 
} 

のようなあなたのStudentクラスでComparableインタフェースを実装するお勧めします。そして、組み込みのソート

List<Student> list = new ArrayList<Student>(); 
... 
Collections.sort(list); 

それともComparableを実装し、独自に設計することができないように使用しますコンパレータ

public class MyComparator implements Comparator<Student> { 

    public int compare(Student o1, Student o2) { 
     //implement the comparator 
    } 

    public boolean equals(Object o) { 
     //implement the equals 
    } 
} 

そして、あなたはこれを行うには、一般的な方法はComparatorを受け入れる任意の種類に一般的なソートアルゴリズムを記述し、その後、別のフィールドでソートするために、異なるComparator Sを書くことです

Collections.sort(list, MyComparator); 
+1

'Comparable'は、毎回同じことでソートしている場合にのみ機能します。 –

+0

@LouisWasserman true – twain249

1

Collection's sortメソッドを使用することができます。

1

次のようになります。

例えば、名前コンパレータはあるかもしれませんLamda expressions and method referencesを使ってコンパレータを定義するクールな方法。

のは、私たちはクラスを持っているとしましょう:

class Jedi { 
    private final String name; 
    private final int age; 
    //... 
} 

し、それらのコレクション:

List<Jedi> jediAcademy = asList(new Jedi("Obiwan",80), new Jedi("Anakin", 30)); 
sort(jediAcademy, (j1, j2) -> j1.getAge() > j2.getAge() ? 1 : j1.getAge() < j2.getAge() ? -1 : 0); 
System.out.println(jediAcademy); //Anakin, Obiwan 

またはメソッドの参照とを、ジェダイは、コンパレータ(同じシグネチャ)として動作方法を持っていると仮定

class Jedi { 
    public static int compareByAge(Jedi first, Jedi second){ 
    return first.age > second.age ? 1 : first.age < second.age ? -1 : 0; 
    } 
    //... 
} 

これは、以下のように使用して、メトd参照:

List<Jedi> jediAcademy = asList(new Jedi("Obiwan",80), new Jedi("Anakin", 30)); 
sort(jediAcademy, Jedi::compareByAge); 
System.out.println(jediAcademy);//Anakin, Obiwan 
+0

+1:コンパイラについては非常にクールな方法。私はこのようなことがすぐに深く統合されるのを見ていると思います。非常に使いやすい。 – MattDavBen

+0

@Mathew実際には、上で共有したプレビューをダウンロードしてインストールするだけで、今すぐ試すことができます:-) –

0

使用する複数のコンパレータ

class Student 
{ 

     String lastName; 
     dounle GPA; 
     int userId 


    static Comparator<Student> getStudentLastNameComparator() { 
     return new Comparator<Student>() { 

      @Override 
      public int compare(Student Student1, Student Student2) { 
       return Student1.getlastName().compareTo(Student2.getlastName()); 
      } 
      // compare using Student lastName 
     }; 
    } 

    static Comparator<Student> getStudentGPAComparator() { 
     return new Comparator<Student>() { 

      @Override 
      public int compare(Student Student1, Student Student2) { 
       if(Student1.GPA < Student2.GPA) 
        return 1; 
       else 
        return -1; 
      } 
      // compare using Student GPA 
     }; 
    } 

    static Comparator<Student> getStudentUserIdComparator() { 
     return new Comparator<Student>() { 

      @Override 
      public int compare(Student Student1, Student Student2) { 
       if(Student1.userId < Student2.userId) 
        return 1; 
       else 
        return -1; 
      } 
      // compare using Student userId 
     }; 
    } 
}