Comparable VS Comparator
22282 ワード
Javaで比較が必要な機能(ex.ソート)を実装する場合は、CompareableまたはComparatorを使用する必要があります.
参考にして判断する対象がある場合は、直接比較対象(comparable)に問い合わせるか、3番目の対象(comparator)に問い合わせることができます.
メソッドを再定義し、比較のためにメソッドを呼び出す必要があります.
ただし、比較的大きい場合は、次のようにして戻り値を決定する必要があります.
戻り値の意味負数-私は小さい 0-両者は同じです. 羊水-私は大きいです. Comparable?
compareToを実現する場合、x、Yに対してsgn(x.compareTo(y)=-sgn(y.compareTo(x))を満たすべきである.
->どちらかに異常が発生した場合、もう一方にも異常が発生します. compareToを実現するには、物性を満たす必要があります.
(x.compareTo(y)>0&y.compareTo(z)>0)はx.compareTo(z)>0であるべきである. 要約すると、x>yはyyはy>zはx>zは成立することを表す.
以上のすべての事項はx.compareTo(y)=0の時にも成立しなければならない.
compareToは同治性検査ではなく順番比較です.
重要なのは、追加の(x.compareTo(y)==0)=(x.equals(y))を実現することです.
このComparableは、Javaで組み込み関数として使用されるソートに標準を提供します.
これらの条件は、Compareableインタフェースの正式なドキュメントを表示することで理解できます.
このインタフェースはクラスの自然な順序に従うべきで、クラスのcompareTo方法も自然な比較方法を採用すべきである.
とても自然な順序(原文naturalOrder)が少しぼやけています
一体何が自然なのか.
これに対する答えは、いくつかの例を見ると感じられます.文字 を辞書順に表示数字は昇順に 並べられている.
これらの約束に従う.
約束を守らない順序(ex.逆順序ソートなど)はJavaの立場では自然ではなく、規定された約束以外の条件でソートしたいならcomparatorを使うべきです.
Comparator
参考にして判断する対象がある場合は、直接比較対象(comparable)に問い合わせるか、3番目の対象(comparator)に問い合わせることができます.
メソッドを再定義し、比較のためにメソッドを呼び出す必要があります.
ただし、比較的大きい場合は、次のようにして戻り値を決定する必要があります.
戻り値の意味
Comparable?
オブジェクト自体を他のオブジェクトと比較する方法
Compareableを実装するクラスは、Compareableインタフェースを使用するために作成されたコレクションインプリメンテーションと完全に互換性があります.
比較時にcomparableに変換して比較するので、comparableを実現するオブジェクト間でしか比較できません.そうでない場合、ClassCastExceptionが放出されます.
比べ物にならない子だけが比較できる.
Javaプラットフォームライブラリに含まれるvalueclassのほとんどがComparableインタフェースを実装しています.
CompareToを実施する際に注意すべき事項
cf)sgn(expression)は、数学のsignum関数であり、-1、0、および1の値を返します.
返される値は、式の値が負か正かによって異なります.
->どちらかに異常が発生した場合、もう一方にも異常が発生します.
(x.compareTo(y)>0&y.compareTo(z)>0)はx.compareTo(z)>0であるべきである.
以上のすべての事項はx.compareTo(y)=0の時にも成立しなければならない.
compareToは同治性検査ではなく順番比較です.
重要なのは、追加の(x.compareTo(y)==0)=(x.equals(y))を実現することです.
このComparableは、Javaで組み込み関数として使用されるソートに標準を提供します.
これらの条件は、Compareableインタフェースの正式なドキュメントを表示することで理解できます.
このインタフェースはクラスの自然な順序に従うべきで、クラスのcompareTo方法も自然な比較方法を採用すべきである.
とても自然な順序(原文naturalOrder)が少しぼやけています
一体何が自然なのか.
Comparentでの自然注文
これに対する答えは、いくつかの例を見ると感じられます.
これらの約束に従う.
約束を守らない順序(ex.逆順序ソートなど)はJavaの立場では自然ではなく、規定された約束以外の条件でソートしたいならcomparatorを使うべきです.
Comparator
コンパレータ使用時
Compareableが実装されていない場合、または少し特殊な順序関係を使用する場合に使用できます.
複数の条件にソートするには、comparatorで条件文で処理します.
Comparatorを使用するとComparableのCompareToは無視されるため、比較するオブジェクトにComparatorがある場合でも、Comparatoで定義されたCompareeToではなく比較を確認します.
最大の利点は、compareToを再定義することなく、必要に応じてソートできることです.
サマリ
店は私の家のほうが安いと言っていますが、比較すると
コンパレータ
ソートを行うアルゴリズム自体を変えるのではなく,比較の仕方を変えて決定順序の判断を変える.
インプリメンテーション
Comparable
クラスを作成し、比較可能性を実装するには、次のようにします.public class Student implements Comparable<Student>//이걸 막으면 compareTo를 만들어놔도 안된다.
{
int no, score;
public Student(int no, int score) {
this.no = no;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"no=" + no +
", score=" + score +
'}';
}
// 음수 내가 작다 --> 둘을 그대로
// 0 둘이 같다 --> 둘을 그대로
// 양수 내가 크다 --> 서로 바꿈
//@Override
public int compareTo(Student o) {
if(this.score==o.score){
if(this.no == no) return 0;
return this.no>o.no?1:-1;
}
return this.score>o.score?-1:1;
}
@Override
public int compareTo(Student o){
return this.no - o.no;
return o.no - this.no;
return Integer.compare(this.no,o.no);
return Integer.compare(o.no,this.no);
}
}
cf)Integerは自己比較の方法を実施した.
Comparator
public class ComparatorTest {
static class StudentComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return 0;
}
}
public static void main(String[] args) {
Student[] students = {
new Student(1, 10),
new Student(3, 50),
new Student(2, 80),
new Student(4, 10)
};
System.out.println("정렬 전 : " + Arrays.toString(students));
Arrays.sort(students,new StudentComparator());
System.out.println("점수기준 오름차정렬 후 : " + Arrays.toString(students));
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.score-o1.score;
}
});
Arrays.sort(students,
//타입 유추가 가능하면 타입 생략 가능.
(Student o1, Student o2)-> {
( o1, o2)-> {
return o2.score-o1.score;
}
(o1, o2)-> o2.score-o1.score
);
//다중 조건 정렬
//block을 줘도 좋지만 삼항연산자로 잡고 가도 좋다.
Arrays.sort(students,(o1,o2)->o2.score != o1.score? o2.score-o1.score:o2.no-o1.score);
System.out.println("점수 기준 내림차순 정렬 후 :"+Arrays.toString(students));
int[][] studentsArray = {
{1,10},
{3,50},
{2,80},
{4,10}
};
Arrays.sort(studentsArray, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0]-o2[0];
}
});
Arrays.sort(studentsArray,(o1, o2)->o1[0]-o2[0]);
}
}
店は私の家のほうが安いと言っていますが、比較すると
コンパレータ
ソートを行うアルゴリズム自体を変えるのではなく,比較の仕方を変えて決定順序の判断を変える.
インプリメンテーション
Comparable
クラスを作成し、比較可能性を実装するには、次のようにします.public class Student implements Comparable<Student>//이걸 막으면 compareTo를 만들어놔도 안된다.
{
int no, score;
public Student(int no, int score) {
this.no = no;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"no=" + no +
", score=" + score +
'}';
}
// 음수 내가 작다 --> 둘을 그대로
// 0 둘이 같다 --> 둘을 그대로
// 양수 내가 크다 --> 서로 바꿈
//@Override
public int compareTo(Student o) {
if(this.score==o.score){
if(this.no == no) return 0;
return this.no>o.no?1:-1;
}
return this.score>o.score?-1:1;
}
@Override
public int compareTo(Student o){
return this.no - o.no;
return o.no - this.no;
return Integer.compare(this.no,o.no);
return Integer.compare(o.no,this.no);
}
}
cf)Integerは自己比較の方法を実施した.
Comparator
public class ComparatorTest {
static class StudentComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return 0;
}
}
public static void main(String[] args) {
Student[] students = {
new Student(1, 10),
new Student(3, 50),
new Student(2, 80),
new Student(4, 10)
};
System.out.println("정렬 전 : " + Arrays.toString(students));
Arrays.sort(students,new StudentComparator());
System.out.println("점수기준 오름차정렬 후 : " + Arrays.toString(students));
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.score-o1.score;
}
});
Arrays.sort(students,
//타입 유추가 가능하면 타입 생략 가능.
(Student o1, Student o2)-> {
( o1, o2)-> {
return o2.score-o1.score;
}
(o1, o2)-> o2.score-o1.score
);
//다중 조건 정렬
//block을 줘도 좋지만 삼항연산자로 잡고 가도 좋다.
Arrays.sort(students,(o1,o2)->o2.score != o1.score? o2.score-o1.score:o2.no-o1.score);
System.out.println("점수 기준 내림차순 정렬 후 :"+Arrays.toString(students));
int[][] studentsArray = {
{1,10},
{3,50},
{2,80},
{4,10}
};
Arrays.sort(studentsArray, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0]-o2[0];
}
});
Arrays.sort(studentsArray,(o1, o2)->o1[0]-o2[0]);
}
}
public class Student implements Comparable<Student>//이걸 막으면 compareTo를 만들어놔도 안된다.
{
int no, score;
public Student(int no, int score) {
this.no = no;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"no=" + no +
", score=" + score +
'}';
}
// 음수 내가 작다 --> 둘을 그대로
// 0 둘이 같다 --> 둘을 그대로
// 양수 내가 크다 --> 서로 바꿈
//@Override
public int compareTo(Student o) {
if(this.score==o.score){
if(this.no == no) return 0;
return this.no>o.no?1:-1;
}
return this.score>o.score?-1:1;
}
@Override
public int compareTo(Student o){
return this.no - o.no;
return o.no - this.no;
return Integer.compare(this.no,o.no);
return Integer.compare(o.no,this.no);
}
}
public class ComparatorTest {
static class StudentComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return 0;
}
}
public static void main(String[] args) {
Student[] students = {
new Student(1, 10),
new Student(3, 50),
new Student(2, 80),
new Student(4, 10)
};
System.out.println("정렬 전 : " + Arrays.toString(students));
Arrays.sort(students,new StudentComparator());
System.out.println("점수기준 오름차정렬 후 : " + Arrays.toString(students));
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.score-o1.score;
}
});
Arrays.sort(students,
//타입 유추가 가능하면 타입 생략 가능.
(Student o1, Student o2)-> {
( o1, o2)-> {
return o2.score-o1.score;
}
(o1, o2)-> o2.score-o1.score
);
//다중 조건 정렬
//block을 줘도 좋지만 삼항연산자로 잡고 가도 좋다.
Arrays.sort(students,(o1,o2)->o2.score != o1.score? o2.score-o1.score:o2.no-o1.score);
System.out.println("점수 기준 내림차순 정렬 후 :"+Arrays.toString(students));
int[][] studentsArray = {
{1,10},
{3,50},
{2,80},
{4,10}
};
Arrays.sort(studentsArray, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0]-o2[0];
}
});
Arrays.sort(studentsArray,(o1, o2)->o1[0]-o2[0]);
}
}
Reference
この問題について(Comparable VS Comparator), 我々は、より多くの情報をここで見つけました https://velog.io/@hongcheol/Comparable-VS-Comparatorテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol