compareToについて

このQ&Aのポイント
  • JavaのArrays.sortメソッドのcompareTo(Object g)について詳しく教えてください。
  • -(age - ((Girl)g).age)の意味がわかりません。説明していただけますか?
  • Girlクラスのオブジェクトを比較するために使われる、compareToメソッドについて教えてください。
回答を見る
  • ベストアンサー

compareToについて

質問なのですが、 package projecjava4t; import java.util.Arrays; /** * Program の概要の説明です */ public class Program { public static void main(String[] args) { Girl[] a=new Girl[4]; a[0] = new Girl("candy", 100); a[1] = new Girl("Lisa", 1010); a[2] = new Girl("Ann",1020); a[3] = new Girl("Eliza",1030); Arrays.sort(a); int i; for(i=0;i<a.length;i++)   a[i].disp(); } } class Girl implements Comparable { String name; int age; public Girl(String s, int a){ name = s; age = a; } public void disp(){ System.out.println("名前"+name+"年齢"+age); } public int compareTo(Object g){ return -(age - ((Girl)g).age); } } のArrays.sort(a)のcompareTo(Object g)では、どのようなことが起きてるのかわかりません。 あと、-(age - ((Girl)g).age)の意味がよくわからないのですが、 わかる方いらしたらご教授よろしくお願いします。

  • 79562
  • お礼率68% (164/239)
  • Java
  • 回答数3
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • osumitan
  • ベストアンサー率33% (102/307)
回答No.2

Arrays.sort(Object[] a)は、配列aの要素を並べ替えます(ソート)。 効率よくソートするアルゴリズムにはいろいろあるのですが、どれも (1)2つの要素を比較してどちらが前か判定する (2)(1)の操作を効率のよい順序で行っていく ということに尽きます。 Arrays.sort(Object[] a)は、(2)のロジックを行いますが、 (1)の比較条件は、各アプリケーションの都合によるので、 Arrays.sort(Object[] a)が決めることはできません。 比較条件はアプリケーション作成者が与える必要があります。 比較条件の与え方は2通りあります。 1つはjava.util.Comparatorを使う方法です。 Comparatorを実装したクラスのインスタンスが判定役となり、 与えられた2つの比較対象を比較条件によって決定します。 今回の方法とは異なるので、詳細は割愛します。 もう1つは今回の方法であるjava.lang.Comparableを使う方法です。 Comparableは、比較対象となるインスタンスに実装します。 比較対象は、自分自身と引数で渡された相手を比較し、 自分が前なら負数、同じなら0、自分が後なら正数を返します。 その判定に使われるメソッドが、int compareTo(Object o)です。 質問の例では、compareToはこうなっています。 public int compareTo(Object g) {  return -(age - ((Girl)g).age); } 自分のageから相手のageを引き、その符号を逆転しています。 自分のage>相手のageのとき、負の値を返します。 自分のage=相手のageのとき、0を返します。 自分のage<相手のageのとき、正の値を返します。 つまり、ageが大きい方が前にくるようになります。 言い換えれば「ageの降順」というやつですね。

79562
質問者

お礼

回答ありがとうございます。 >>ageが大きい方の前にくるようになります このageは自分のageと相手のageの大きいほうのことでいいのでしょうか?

その他の回答 (2)

  • osumitan
  • ベストアンサー率33% (102/307)
回答No.3

No.2です。 > このageは自分のageと相手のageの大きいほうのことでいいのでしょうか? int compareTo(Object o)の戻り値は、引数で渡された相手と比べて ・自分の並び順が前になるときは負の値(<0) ・自分の並び順が後になるときは正の値(>0) ・同じときは0 になります。 符号だけ気をつければ絶対値はいくつでも関係ないので、 どんな判定方法で戻り値を決めてもいいんですが、 数値を比較するときは、たいてい引き算の結果で返します。 条件が昇順(=小さい値が前)なら、「自分-相手」です。 この例ではたぶん条件を降順(=大きい値が前)にしたいので、 頭にマイナスをつけてるわけです。

  • koko_u_u
  • ベストアンサー率18% (216/1139)
回答No.1

>Arrays.sort(a)のcompareTo(Object g)では、 >どのようなことが起きてるのかわかりません。 Arrays は「配列」の一般なので、実際に格納されているオブジェクトが Girl オブジェクトかどうかを知りません。 Arrays.sort() が必要とするのは、配列に格納されているオブジェクトが 「比較可能」であることだけです。 そのためにあなたは Comparable インターフェイスを実装したのです。 >-(age - ((Girl)g).age)の意味がよくわからないのですが、 年齢で比較するという意味です。 Arrays.sort(T[] a, Comparator<? super T> c) のジェネリックなバージョンを 使った方がよいと思いますけど。

79562
質問者

お礼

回答ありがとうございます。 >-(age - ((Girl)g).age)の意味がよくわからないのですが、 なのですが、どうやって年齢を比較してるのかどうか知りたいのです。 どうかご教授よろしくお願いします。

関連するQ&A

  • 配列の初期化

    java初心者です 配列の初期化についてなのですが、たとえば String[] name = {"A","B","C","D","E","F","G","H","I","J"}; int[] age = {12,18,25,18,20,32,22,15,30,37,29,24}; とありこれを10代/20代/30代に分けるとして int[] age10 = new int[?]; int[] age20 = new int[?]; int[] age30 = new int[?]; と宣言したいのですが、?にはなにを入れればいいのでしょうか? int[] ageのところから自分で数えて4/5/3と入れるのは無しです。 お手数ですがアドバイスや解説おねがいしますm(_ _)m

    • ベストアンサー
    • Java
  • クラス名を変えるとコンパイルが通らない

    interface HINA { void write(String str, int age); } class super_class { String name; int age; public void write(String str, int age){ System.out.println(str + "\t" + age); } super_class(String name, int age) { this.name = name; this.age = age; } } class sub_class extends super_class implements HINA { public void write(String str , int age) { System.out.println(str + "\t" + age); } sub_class(String str , int age) { super(str , age); } } public class test3 { public static void main(String[] args) { super_class naru = new super_class("成瀬川なる", 17); super_class shinobu = new sub_class("前原しのぶ", 13); sub_class motoko = new sub_class("青山素子", 15); if (naru instanceof HINA) naru.write(naru.name, naru.age); if (shinobu instanceof HINA) shinobu.write(shinobu.name, shinobu.age); if (motoko instanceof HINA) motoko.write(motoko.name, motoko.age); } } これのsuper_classをOyaに、sub_classをKoにするとコンパイルエラーになります。 何故なんでしょう。 分かる方がいましたら、教えて下さい。 どうぞ宜しくお願い致します。 それと見づらくてどうもすいません。

    • ベストアンサー
    • Java
  • コンポジション コンストラクタに引数がある場合

    class Person{ public String name_; public int age_; public Person(String n,int a){ name_ = n; age_ = a; } } class Student{ public Person person_; public int grade_; public Student(Person p,int g){ person_ = new Person("MOTO",2); grade_ = g; } } public class Samconp2{ public static void main(String[] args){ Student asaya_ = new Student(p,0); } System.out.println(asaya_.person_.name+asaya_.person_.age_+asaya_.grade__); } 3のプログラムを見るようにコンストラクタに引数使い、又継承を使わないでPerson クラスのname_ age_ それを拡張したStudetクラスのgrade_をmain関数で表したいのですが(希望としてはname_ "Moto" age_ 2 grade_ 0) 結果としては、System.out.println(asaya_.personn_.name_ + asaya_.person_.age_ +asaya_grade_);で<identifierがありません>となります。 まだ初心者で良く分りません。解決方法をお願いします。

    • ベストアンサー
    • Java
  • JavaのArrays.sortについて教えてください

     Javaを勉強している初心者です。 次のプログラムはある学校のある学年の梅組の生徒5人のデータ(出席番号 no、氏名 name、身長 height)を 身長の低い順に並べ替えようとするものです。クラスMainでArrays.sort(ume);を実行するとどんな処理が行われるのか、またクラスStudentのメソッドcompareTo(Object o)はどう関係するのかご教示ください。 import java.util.Arrays; class Student implements Comparable { private int no; private String name; private double height; public Student(int no, String name, double height) { this.no = no; this.name = name; this.height = height; } public int compareTo(Object o) { double h1 = this.height; double h2 = ((Student)o).height; if(h1 == h2) { return 0; } else if(h1 > h2) { return 1; } else { return -1; } } } public class Main { public static void main(String[] args) { Student[] ume = new Student[5]; ume[0] = new Student(2, "木下 薫", 141.5); ume[1] = new Student(5, "湯水 敦", 145.0); ume[2] = new Student(1, "相田 徹", 152.5); ume[3] = new Student(4, "田中 大", 136.0); ume[4] = new Student(3, "橋 航", 145.0); Arrays.sort(ume); } }

  • デストラクタについて

    #include <iostream> #include <string> using namespace std; #define NUM 2 //登録人数 class Person{ char *name; int *age; char *hobby; public: Person() { name = new char; age = new int; hobby= new char; } void Set(char *n,int a,char *h) { name=n; *age=a; hobby=h; } char *Get_name(void) { return name; } int Get_age(void) { return *age; } char *Get_hobby(void) { return hobby; } ~Person() { cout<<name<<"のデストラクタ\n"; delete [] name; delete age; delete [] hobby; } }; int main(void) { Person *p; int i; p=new Person[NUM]; p[0].Set("永嶋",21,"映画鑑賞"); p[1].Set("平林",54,"車"); for(i=0;i<NUM;i++){ cout<<"\n名前:"<<p[i].Get_name(); cout<<"\n年齢:"<<p[i].Get_age(); cout<<"\n趣味:"<<p[i].Get_hobby()<<"\n"; } delete [] p; return 0; } というプログラムを作成したのですが デストラクタの3つのdeleteがおかしいようなのですが どのような部分が問題となっているのでしょうか? 回答・アドバイス宜しくお願いいたします。

  • この警告はどうすれば?

    以下のメソッドを含むプログラムをEclipseで作成している際に次のような警告が発生しました。 型の安全性:型Comparator の式は、未検査の型変換を使用してComparator<? super T>に準拠するようにする必要があります。 型の安全性:型 Arrays の総称メソッド sort(T[], Comparator<? super T>)の未検査の呼び出し sort(Object[],Comparator)がありました。 コンパイルして実行する分には、なんら問題ないのですが、この警告の意味と解決策が分からないままにしておくのは気持ち悪いので、分かる方がいらしたら教えてください。 static void sortName(){  String array[] = new String[4];  array[0] = "abba";  array[1] = "abab";  array[2] = "aaaa";  array[3] = "aabb";  Comparator asc = new Comparator() {   public int compare(Object obj0, Object obj1) {    String nameKana0 = (String)obj0;    String nameKana1 = (String)obj1;    int ret = 0;    ret = nameKana0.compareTo(nameKana1);    return ret;  }  };  Comparator comparator = asc;  Arrays.sort(array, comparator); // 配列をソート  for (int i = 0; i < array.length; i++)   System.out.println(array[i]); }

    • ベストアンサー
    • Java
  • ファイル読込時に構造体の文字列ポインタに割当てたいと

    ファイル読込時に構造体の文字列ポインタに割当てたいと思っています。 (new 演算子を使用します。) 文字列の長さが不定です。 どうすれば、文字列の長さを知ることができますか? 以下のようなところまでは作れましたが、 困っています。 void loaddata()のfscanf関数の部分です。 ほかにも関数の void outputdata() void deletedata() がありますが、長いので省略しました。 ********************************************************** #include<stdio.h> #include<string.h> class data { public: struct basic { char *name; int age; struct basic *next; }; private: struct basic *base; struct basic *base_top; int cnt; public: data::data() { cnt=0; } void inputdata(char *name,int age) { if(cnt==0) { base=new basic; base_top=base; base->age=age; int len=strlen(name); base->name=new char[len+1]; strcpy(base->name,name); cnt++; } else { base->next=new basic; base=base->next; base->age=age; int len=strlen(name); base->name=new char[len+1]; strcpy(base->name,name); cnt++; } } void savedata() { base=base_top; FILE *fp; fp=fopen("dat.txt","w"); for(int i=0;i<cnt;i++) { fprintf(fp,"%s\t%d\n",base->name,base->age); base=base->next; } fclose(fp); } void loaddata() { if(cnt!=0){deletedata();} cnt=0; FILE *fp; fp=fopen("dat.txt","r"); while(1) { fscanf(fp,"%s\t%d\n",base->name,base->age); } } };

  • 配列の抽出

    たびたび失礼します 以下のようなプログラムを記述しました private String[] setWorst(String[] score,String[] score2,String[] score3){ //ソート Data[] Datas = new Data[score.length]; for(int i = 0; i < Datas.length; i++){ Data Data = new Data(); Datas[i] = Data; Data.score = Integer.valueOf(score[i]); Data.s_indicator = s_indicator[i]; Data.center = center[i]; } ScoreComparator scoreComparator = new ScoreComparator(); Arrays.sort(Datas,scoreComparator); //ワーストの抽出 ArrayList worst3 = new ArrayList(); public class Data{ Integer score; String score2; // String score2; // } public class ScoreComparator implements Comparator{ public int compare(Object o1, Object o2){ Data Data1 = (Data)o1; Data Data2 = (Data)o2; int result = Data1.score.compareTo(Data2.score); return result; } } 変数scoreを中心としたソートを作成しました。 次にscoreの値を読み込んで下位4つを抜き出してArrayList worst3に格納していきたいと思っています。 scoreには0~10の数字が入っていますので0~3を抜き出したいということです。 自分でもいろいろ試しましたが、なかなか良い考えが浮かばないので知恵を借りたいと思います。 ヒントやアイデアだけでも結構ですので、よろしくお願いします。

  • 配列の中を変更

    入力したnameに、入力したageの数だけ文字を進める(例えばnameがOda、ageが12→表示結果がAmp)にする関数を作成しようとしたのですが、やり方がまったくわかりません。 そもそもこのような場合、文字1つ1つに別の配列を使わなければならないのでしょうか? #include <stdio.h> #define N 1 #define NAME 20 typedef struct{ char name[NAME]; char age; } person; int main(void){ int i; person persons[N]; for(i=0;i<N;i++){ printf("name > "); scanf("%s" , persons[i].name); printf("age > "); scanf("%d" , &persons[i].age); } for(i=0;i<N;i++){ printf("name = %s\n" , persons[i].name); printf("age = %d\n" , persons[i].age); } return 0; }

  • StringクラスのcompareToメソッド

    ArrayListに登録した文字列を五十音順にソートしようと思いComparator を使用して 以下のようなサンプルプログラムを作ってみました。 ところが想定していたような {赤ちゃん、富士山、山口県}とはならず {富士山、山口県、赤ちゃん} というような結果になりました。 compare() の戻り値の部分を return ((String)arg1).compareTo((String)arg0); に変更しても{赤ちゃん、山口県、富士山} となり辞書の並びとは異なる結果になりました。 辞書順に並べるにはなにかよい方法はありますでしょうか。 public class compareTest { public static void main(String[] args) { ArrayList<String> array = new ArrayList<String>(); String a = "赤ちゃん"; String b = "山口県"; String c = "富士山"; array.add(a); array.add(b); array.add(c); for(int i=0;i<array.size();i++) { System.out.println("ソート前=" + array.get(i)); } Collections.sort(array, new testComp()); for(int i=0;i<array.size();i++) { System.out.println("ソート後=" + array.get(i)); } } } public class testComp implements Comparator { public int compare(Object arg0, Object arg1) { return ((String)arg0).compareTo((String)arg1); } }

    • ベストアンサー
    • Java

専門家に質問してみよう