• 締切済み

ComparableとComparatorの違いについてわからなくて困っています。

ComparableとComparatorの違いについてわからなくて困っています。 以下のURLのサイトを記事を見ているのですが、 http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000179.html http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000180.html java.lang Comparableインタフェース メソッド public int compareTo(Object o) java.util Comparatorインタフェース メソッド public int compare(Object o1, Object o2) public boolean equals(Object obj) これらの違いについてなのですが、URLの記事では、 ・Comparableインターフェイスの実装クラスにしてcompareTo()メソッドを実装するのは、比較対象が明確であり、比較結果が一般的に分かりやすく容易に想像できる場合にのみとした方がよい ・Comparatorは任意の順番でソートしたい場合にも使用できる。例えば、昇順ではなく降順でソートしたい場合や、複数のデータを持つクラスについて細かく比較方法する場合 と記事にありますが、説明がうまく解釈できないです。 ・Comparableは主にラッパークラスやStringなどで使用するためのものなのでしょうか?(実装してるからそうだとは思いますが) 比較対照が明確なので compareToのreturn文で 除算するだけで可能? ・ComparatorはArraysやコレクション、自作クラス向けに任意の順番でソートするためのものなのですか? 自作クラスについてはComparableでもcompareTo()をオーバーライドすれば同じことが可能? 通常はComparator実装クラスのcompare()の中にreturn文でcompareTo()を使用しているような気もします。 この方法だとObject型で引数を渡して、int型に変換して比較になると思いますが、 StringだとComparableを実装してるから、戻り値でint型が返るのかな、 public int compare(String s1, String s2) { return s2.compareTo(s1) } つまり、自作クラスはインスタンスフィールドにある基本型やObject型(String, Integerなど)の値を使い、 基本型においては除算を使用し、オブジェクト(Comparableを実装しているもの)に対してはcompareTo()で比較するのでしょうか? (これで解決したような気もしますが) 質問がわかりずらくてすみません。何か解釈の間違いがあればご指摘お願いします。

  • Java
  • 回答数1
  • ありがとう数2

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

英語としての「comparable」と「comparator」の違いは分かりますか? 本質的にはそれがすべてでしょう. 大雑把には ・(同じクラスの他のオブジェクトと) 比較可能であることを示すのが Comparable ・(他のクラスの) 2つのオブジェクトを比較するのが Comparator だから, 混乱する余地もないはず.

関連するQ&A

  • ソート Comparator

    Integer型の変数num(10,4,8,6,9,5)をそれぞれ含むオブジェクト配列aryがあり、それをソートするため Arrays.sort(arry,sortLogic); とした場合、 Comparatorインターフェースを実装したクラスsortLogic内のメソッドで public int compare(Object object1, Object object2) {   return ((ary)object1).compareTo(((ary)object2).num); } とすると、昇順にソート(修正ソートマージ)、また、 return ((ary)object1).compareTo(((ary)object2).num); とすると降順にソートされるみたいなのですが、どのような手順(アルゴリズム)でソートされるのでしょうか?

    • ベストアンサー
    • Java
  • JavaのComparatorを使ったソート

    Javaのバージョンは1.5です。 Comparatorクラスをimplementsしたクラスを使用して ソートを行おうとしています。 compareメソッドは二つの引数を比較した結果を返してくれますが、 日本語を比較した場合に何をもって大小を比較するのでしょうか? 日本語の入った項目(総務、経理、開発、人事等が入っています)をキーに ソートさせた場合の結果がよくわからないソートになりました。 日本語の音読みにソートさせたいのですが…。

    • ベストアンサー
    • Java
  • この警告はどうすれば?

    以下のメソッドを含むプログラムを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
  • 多次元配列のソートがうまくいかない

    多次元配列のソートがうまくいかない 質問失礼します. 以下のような,String型,int型,double型の混在した多次元配列([3][3]の配列)をソートするプログラムを作成しました. このプログラムでは3番目の項目でソートを行っています. 問題点なのですが, 3番目の項目がdouble型の一桁(例えばarray[1][2]が2.0)ならばうまくソートできるのですが, 一つを2桁(例えばarray[1][2]を10.0)にすると何故か先頭の数(10.0の場合1)を基準にソートされてしまっているようです・・・ 配列へのデータの入れ方が間違っているのでしょうか? 原因がはっきりわからず困っているのですが, わかる方いましたらよろしくお願いします. public class Sort_test { /** * @param args */ public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ String[][] array = new String[3][3]; array[ 0 ][ 0 ] = "A"; array[ 0 ][ 1 ] = 2001+""; array[ 0 ][ 2 ] = 9.0+""; array[ 1 ][ 0 ] = "B"; array[ 1 ][ 1 ] = 1001+""; array[ 1 ][ 2 ] = 2.0+""; array[ 2 ][ 0 ] = "C"; array[ 2 ][ 1 ] = 3001+""; array[ 2 ][ 2 ] = 6.0+""; TheComparator comparator = new TheComparator(); // 3番目の項目でソートするように設定 comparator.setIndex( 2 ); // ソート実施 Arrays.sort( array, comparator ); dump(array); } public static void dump( String[][] array ) { for ( int i = 0;i < array.length;i++ ) { for ( int j = 0; j < array[ i ].length;j++ ) { System.out.print( "\t" + array[ i ][ j ] ); } System.out.println(); } } } //多次元配列ソート用クラス class TheComparator implements Comparator { /** ソート対象のカラムの位置 */ private int index = 0; /** ソートするためのカラム位置をセット */ public void setIndex( int index ) { this.index = index; } public int compare( Object a, Object b ) { String[] strA = ( String[] ) a; String[] strB = ( String[] ) b; return ( strA[ index ].compareTo( strB[ index ] ) ); } }

    • ベストアンサー
    • Java
  • Comparatorを使用したソートについて

    Javaのバージョンは1.5です。 Comparatorを使用してソートを行っています。 ソートをシフトJISコード順とするため 下記のようなクラス、メソッドを作成しています。 public class ExmComparator implements Comparator<Object> { public int compare(Object obj1, Object obj2) { byte[] b1 = obj1.toString().getBytes("SJIS"); byte[] b2 = obj2.toString().getBytes("SJIS"); int len; if (b1.length < b2.length) { len = b1.length; } else { len = b2.length; } int s1h, s2h; for (int i = 0; i < len; i++) { s1h = b1[i]; s2h = b2[i]; if (!(s1h == s2h)) { return s1h - s2h; } } return b1.length - b2.length; } } ソートするキー(名称+コード)が "-0001","テレビ0002","電話0003","PC0004"の場合はシフトJISコードの昇順に "-0001","PC0004","テレビ0002","電話0003"としたいのですが、 "テレビ0002","電話0003","-0001","PC0004"とソートされてしまいます。 半角ハイフンは名称がない場合の代替名称です。 シフトJISコードは - :0x002d P :0x0050 テ:0x30c6 電:0x9364 なのでこの通りにソートされるのではないかと思ったのですが、 2バイト文字はどうなんでしょうか…。

    • ベストアンサー
    • Java
  • 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
  • STLのsortで、プライベート変数を比較関数に組み入れたい。

    STLのsortで、プライベート変数を比較関数に組み入れたい。 STLのvectorのsortで比較関数を指定してソートをしようとしております。 ソートしようとするvectorは、とあるクラスのプライベート変数であり、 同じクラスの他のプライベート変数を利用した比較を行おうとしています。 例えば int array[4] = {1, 7, 3, 5}; なるプライベート変数があり、比較関数はこんなアルゴリズムとしたいと。 bool compare(int left, int right) { return array[ left ] < array[ right ]; } この compare をクラスのメソッドとして定義して使えるのかなと思っていたのですが コンパイルしたところエラーが出ました。パブリック変数にして、プレディケートの ためのクラスを作って、そこでパブリックメソッドを作って……という方法は見つかった のですが、そのような面倒な方法を経なければいけないのでしょうか。

  • ArrayListなどのソート

     いつもお世話になっています。ArrayListなどをソートする際に、Comparatorインターフェースを実装したクラスを利用して、辞書順や数値順などでソートすることは出来ますよね。これを任意の単語の順番にソートするにはどのようにすればよいのでしょうか。つまり、下記例において、文字列順ではなくて、"ONE", "TWO", "THREE", "FOUR"の順番にソートしたいのです。 ArrayList list = new ArrayList(); list.add("THREE"); list.add("ONE"); list.add("FOR"); list.add("TWO");  やはりcompare()メソッド内で総当り的に比較するしかないのでしょうか。  開発環境はJDK1.4です。事情により返答が遅れてしまうかもしれませんが、どうぞ宜しくお願い致します。

    • ベストアンサー
    • Java
  • 繰り返し

    継承を使ったもので、実行するプログラムを public class A22_exec2 { public static void main(String args[]){ for(int i= 0; i <= 10 ; i++){ A22_StrArray a = new A22_StrArray(); for( int j = 1; j <= 10000; j++) a.add(format.format(j)); System.out.println(a.get(5000 - 1)); public void sort(int mode){ Comparator c; public int compare(Object o1, Object o2) { return ((String)o2).compareTo((String)o1); } a.clear(); } } } } としましたが、うまくいきません。 A22_exec2.java:8: 式の開始が不正です。 public void sort(int mode){ ^ A22_exec2.java:14: ';' がありません。 } ^ A22_exec2.java:6: シンボルを解決できません。 シンボル: 変数 format 場所 : A22_exec2 の クラス a.add(format.format(j)); とエラーメッセージがでます。どこを修正すればいいでしょうか? ちなみに『項目を1000個追加し、5000番目の内容を表示。降順ソート。全てクリア。以上を10回繰り返すプログラムを作成する』という事がやりたいです。

  • HashMapデータの並び替えについて

    ファイル名とファイルサイズの複数の組み合わせが入ったHashMap型のインスタンスをファイルサイズ降順に並び替えるコードにおいて、Eclipse上で警告が表示されます。 対処法をお教え頂けませんでしょうか。 〔コード〕 Map<String,Long> filesMap = new HashMap<String,Long>(); (ファイル名とファイルサイズをfilesMapに入れる) // filesMapをファイルサイズの降順に並べる List<Map.Entry<String,Long>> filesEntries = new ArrayList<Map.Entry<String,Long>>(filesMap.entrySet()); Collections.sort(filesEntries, new Comparator(){  public int compare(Object o1, Object o2){   Map.Entry e1 =(Map.Entry)o1;   Map.Entry e2 =(Map.Entry)o2;   return ((Long)e2.getValue()).compareTo((Long)e1.getValue());  } }); 〔警告〕 (Collections.sort(filesEntries, new Comparator(){ 行) この行に複数マーカーがあります - 型の安全性: 型 new Comparator(){} の式は、未検査の型変換を使用して Comparator<? super Map.Entry<String,Long>> に準拠するようにする必要があります - 型の安全性: 型 Collections の総称メソッド sort(List<T>, Comparator<? super T>) の未検査の呼び出しsort(List<Map.Entry<String,Long>>, new Comparator(){}) がありました - Comparator は raw 型です。総称型 Comparator<T> への参照は、パラメーター化する必要があります (Map.Entry e1 =(Map.Entry)o1; 行) (Map.Entry e2 =(Map.Entry)o2; 行) この行に複数マーカーがあります - Map.Entry は raw 型です。総称型 Map<K,V>.Entry<K,V> への参照は、パラメーター化する必要があります - Map.Entry は raw 型です。総称型 Map<K,V>.Entry<K,V> への参照は、パラメーター化する必要があります 2012 Feb. 04.

    • ベストアンサー
    • Java

専門家に質問してみよう