• ベストアンサー

どのようにソートすればいいのか教えて下さい

AとBとCにそれぞれ数値を与えておいて、その数値の大きい順にABCを並べ替えるようにしたいのです。一応、下のようにアルファベットと数値の間にはカンマを入れて分けています。 A, 5-------→B, 9 B, 9-------→C, 7 C, 7-------→A, 5 このように並べ替えたいのですが、うまくいきません。ArrayListを使用しCollectionsクラスのsortメソッドを使ってやれば先頭の文字によるソートはできるのですが、カンマ後の数値での並べ替えの方法がよくわかりません。 いい法方がありましたらおしえてください。

  • Java
  • 回答数4
  • ありがとう数6

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

  • ベストアンサー
  • sasadora
  • ベストアンサー率68% (59/86)
回答No.4

Harry_さんの回答に賛成ですが、 文字列を格納したArrayListの状態からソートしたいのであれば、 次のようにするといいです。 Collections.sortで、Comparatorを指定しない場合は、 中に入っているオブジェクトのcompareToメソッドを使って、 ソートされます。今回はStringオブジェクトが格納されているので、 StringオブジェクトのcompareToメソッドで比較したソート結果 (文字列を辞書的に並べた結果)でソートされます。 これが、hohumanさんが書いたソースで行っていることです。 今回のように自分独自の比較方法を使用したい場合は、 サンプルのように、自分独自のcompareToメソッドを実装した、 Comparatorを作成して、それをsortするときに使えばいいです。 import java.util.*; public class Sortable{   private static ArrayList names; // 名前を格納するArrayList      public static void main(String[] args){     names = new ArrayList(); // ArrayListオブジェクトの生成          //ファイルから読み込み     readN();     //自分で作ったComparableを使って、ソート     Collections.sort(names, new MyComparator());          for (int i = 0; i < names.size(); i++){       System.out.println(names.get(i));     }   }      //名前をファイルから読み込んでArrayListに格納(しているふり)   private static void readN(){     names.add("C, 9");     names.add("B, 2");     names.add("A, 7");   }   //カンマ後の数値でソートするComparator   private static class MyComparator implements Comparator{     public int compare(Object obj1, Object obj2) {       //文字列データから、ソート対象となる数値を取得       int num1;       int num2;              String str1 = obj1.toString();       String str2 = obj2.toString();              num1 = Integer.parseInt(str1.substring(str1.indexOf(',') + 1).trim());       num2 = Integer.parseInt(str2.substring(str2.indexOf(',') + 1).trim());              return num2 - num1;     }   } } ただし、比較するときに、毎回文字列を解析して、 数値の部分を取り出しているので効率は悪いです。 あと、文字列データの仕様が分からないので、 上記ソースは、カンマの後に数値とスペース以外の文字列があると、 数値部分の取り出しに失敗します。 その辺は、実際のデータに合わせて適切な数値部分のとり方を 実装してください。

hohuman
質問者

お礼

これを参考にさせてもらいテキストファイルから読み込んだデータのソートもうまくできました。 私もこれからもっといろいろ勉強していきたいと思いますので、また分からない所がありましたら教えてください。 Harryさん、sasadoraさん お二人とも本当にどうもありがとうございました。

その他の回答 (3)

  • Harry_
  • ベストアンサー率55% (36/65)
回答No.3

実行例です。クラス名やインポート文は補ってください。 コンパイルはしてません。間違ってたらごめんなさい。 public static void main(String[ ] args) {  Data a = new Data('A', 5) ;  Data b = new Data('B', 9) ;  Data c = new Data('C', 7) ;  List list = Arrays.asList ( new Data[ ]{a, b, c} ) ;  Collections.sort( list ) ;  for ( int i = 0 ; i < list.size() ; i++ ) {   System.out.println( list.get(i) ) ;  } }

hohuman
質問者

補足

うーん、こういうやり方もあるのですね。たいへん勉強になります。 どうもありがとうございます。 しかし今の私の場合、そのように自分でソートするものを入れるのではなく、 テキストファイルなどからその内容を一行一行読み込んでいってソートするように させています。とりあえず、普通にソートできる状態のものを載せておきます。 (Data2.java) import java.io.*; //入出力 import java.util.*; class Data2 { private static ArrayList names; // 名前を格納するArrayList public static void main(String[] args) { names = new ArrayList(); // ArrayListオブジェクトの生成 readN(args[0]); sort(); print(); } // 名前を ファイルから 読み込んでArrayListに格納 private static void readN(String fileName) { try { FileReader aFileReader = new FileReader(fileName); BufferedReader aInputFile = new BufferedReader(aFileReader); // ファイルの終わりに到達するまで名前を読み込む String aLine; while ((aLine = aInputFile.readLine()) != null) { names.add(aLine); //print(); // 名前が追加されていることを確認のための出力 } aInputFile.close(); } catch (FileNotFoundException e) { } catch (IOException e) { } } // 名前の並び替え private static void sort() { Collections.sort(names); } // 出力 private static void print() { for (int i = 0; i < names.size(); ++i) { System.out.println((String)names.get(i)); } } } で、適当なファイル(ABC.txt)を作ってjava Data2 ABC.txtと入力すると 1番前のアルファベット順にソートされます。 (ABC.txt) C, 9 B, 2 A, 7  ↓ A, 7 B, 2 C, 9 この状態でカンマの後の数字でのソートをやろうとしています。 もしわかるようでしたら教えてくださいませんか?よろしくお願いします。

  • Harry_
  • ベストアンサー率55% (36/65)
回答No.2

No.1 です。ちょっと補足です。 数字を大きい方から順に並べるのであれば、 下の回答の compareTo メソッドの return 1 と return -1 は 逆にしないといけません。

hohuman
質問者

お礼

すみません、補足のは取り消しです。 ただのスペースの問題でした。

hohuman
質問者

補足

回答どうもありがとうございます。 さっそく試してみたのですがコンパイル時にこのようなエラーが発生しました C:\JAVA\Sort4.java:32: \12288 は不正な文字です。  this.alphabet = alphabet; ^ C:\JAVA\Sort4.java:33: \12288 は不正な文字です。  this.number = number; ^ C:\JAVA\Sort4.java:42: \12288 は不正な文字です。   return alphabet + ", " + number; ^ この場合、何が原因なのか分かりますか?

  • Harry_
  • ベストアンサー率55% (36/65)
回答No.1

1レコードのデータをひとつのクラスで表現すべきです。 public class Data {  private char alphabet;  private int number;  public Data(char alphabet, int number) {   this.alphabet = alphabet;   this.number = number;  }  public char getAlphabet() { return alphabet; }  public int getNumber() { return number; } } そして、このクラスに Comparable インターフェースをインプリメントさせ、 compareTo メソッドを実装します。 public class Data implements Comparable { // 上記と同じ // これを追加  public int compareTo(Object obj) {   Data other = (Data)obj;   if (this.number > other.number) {    return 1;   }   else if (this.number < other.number) {    return -1;   }   else {    return 0;   } } そのうえで、このクラスのオブジェクトを格納した List を Collections.sort() でソートすると、数字の大きさでソートできます。 ついでに toString() も実装しておくとよいですね。 public String toString() {  return alphabet + ", " + number; }

hohuman
質問者

補足

>このクラスのオブジェクトを格納した List ・・・ の部分をどのようにすればいいのか、いまいちよくわかりません。 もしよろしければ実行例をお願いできないでしょうか? まだまだ勉強不足なものですみません・・・・・。

関連するQ&A

  • 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
  • 数値の大きい順にソート

    数値の大きい順にソートするにはどのようにしたらよろしいでしょうか? 例えば、 @A = ("10","5","18","6","9"); という配列があるとします。 これを @B = sort @A; とすると、 10,18,5,6,9 となってしまいます。 これを 18,10,9,6,5 のように数値の大きい順に配列Bに代入したいのですが、どうしたらよいでしょうか?よろしくお願いします。

    • ベストアンサー
    • Perl
  • エクセルのソートで、数字よりもアルファベットを優先したい

    数字とアルファベットが混在したコードにソートをかけたいと思っています。 (A~Z、0~9の順にしたい) ユーザー設定リストで新しいリストを登録するんだろうな…までは分かるんですが、やってみてもうまくいきません。 私が試したのは、A、B、C…7、8、9と順に一桁です。 ソートをかけたいコードは*******-*という形です。

  • sortコマンドについて

    ファイルaaaについて、 第1ソートキーを第1列目で数値順に 第2ソートキーを第2列目でアルファベット順に ソートした結果をbbbに出力したいと思います。 sort -n -k 1,1 -d -k 2,2 aaa > bbb としたところ、正しい結果が得られませんでした。 どのようにしたら良いのか教えて下さい。

  • 同期化時のことで

    いつもお世話になっています。 同期化を使用した場合のことで質問します。 private static final List<String> list = Collections.synchronizedList(new ArrayList<String>() ); を使いサーブレットでの同期化を実行しているのですが、 この場合に、値をソート化して処理を実行することは可能なのでしょうか? Collectionsを調べると、可能性としてsynchronizedSetだとできそうな気はするのですが、 その際の直列化の実装がよくわかりません。 考えているソースは以下です。 ** ラップオブジェクト同期化 **/ SortedSet sort = Collections.synchronizedSortedSet(new TreeSet<String>() ); /** サーブレットクラスでの処理 **/ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //リクエストデータ String key = request.getParameter("key"); //リクエストデータをSortedSetに格納する sort.add(key); //←この時点で、直列化のための何らかの処理がいる try{ //実行時、時間をずらすために宣言 Thread.sleep(1000); }catch(Exception e){ } //何の処理もしなかったら、実行された画面の順で処理が開始される synchronized(sort){ for(int a=0;a<10;a++){ System.out.println("a="+a); } } //SortedSetに格納された値の順 List sortList = new ArrayList(sort); for(int s=0;s<sortList.size();s++ ){ //↓すべての処理が終わってみたら、確かにソート化されているs System.out.println("sortList["+s+"]="+sortList.get(s)); } } jsp側のリクエストデータ 1回目 C 2回目 B 3回目 A 実行させたい順 C→A→B このとき、B,Aが渡されるタイミングは、Cの処理が実行中時 また、どのキーに対しての実行中なのかを見ることはできるのでしょうか? Collectionsクラスを見たところなさそうだったのですが。。。 宜しくお願いします。

    • ベストアンサー
    • Java
  • IE の「お気に入り」の "ソート" の関係で

    Windows XP 上で、IE 6.0 を使っています。 IE の「お気に入り」に、  1、2、10、20 のような名前のフォルダがそれぞれあった時に、 これを「名前順で並べ替え」すると、   1   2   10   20 のように並びます。 ところが、別のブラウザの「お気に入り」に同じようにフォルダを作って 「アルファベット昇順」で並べ替えしましたら、   1   10   2   20 のようになりました。 ---- ◎ 「アルファベット昇順」というのは、上で挙げた別ブラウザでの結果のようになるが普通でしょうか? ◎もしそうだとした時に、 IE の「名前順で並べ替え」というのは、 どういう種類のソートなんでしょうか? --

  • エクセルで複数のデータからソートをかけて、合計金額を算出したいのですが

    エクセルで複数のデータからソートをかけて、合計金額を算出したいのですが、ソートではうまくいきません。 A列(文字)  B列(数値)  C列(金額) ABC 123 100 ABC 456 50 DEF 123 1,000 GHI 789 300 このような感じで、B列には同じ数値のものが複数あるデータです。 どなたかエクセルマスターの方、お教えいただけますか?

  • VBA Sortメソッドについて

    VBA初心者です。 並べ替えをしたくてSortメソッドというのを使っているのですが、 Sortメソッドの後にプログラムを書くと 「実行時エラー'1004':アプリケーション定義またはオブジェクト定義エラーです」 と出てしまいます。 Worksheets(sheets).Range("A1:D30").sort _ Key1:=Range("B2"), _ Header:=xlGuess, _ MatchCase:=True, _ SortMethod:=xlPinYin ↑こんなプログラムを2個続けて(sheetsを変えて)実行させ、 その後にもいろいろ続けて書きたいのですがどうしたらいいのでしょう。 「:=」という書き方を初めて使ったのでよく理解できていません。 ご教授いただけると助かります。

  • ソートについて質問です

    いつもご回答ありがとうございます。 今回はソートについて質問させて下さい。 非常に単純な並べ替えですが、 B1~B100に並べられているデータを、B100~B1の順に並べ変えようと思います。 単純に、上下反対に並べ変えると言う事です。 そこで、 Range("B1:B100").Sort Key1:=Columns("B"),Orientation:=xlSortRows と記述したのですが、エラーが出てしまいます。 どこがいけないのでしょうか?

  • ACCESSレポートのソートに関して

    ソートに関して教えて下さい。 現在、レポート出力である帳票を作成していますが、その際のソート順として ある項目の何文字目からをキーとしてソートしたいと考えています。 というのも、ある番号の先頭にアルファベットが存在し、アルファベット+連番という 形となっている為、そのアルファベットを無視して連番だけでソートしたいと考えています。 Oracle等のデータベースで、SQLを用いて取得するような時は、実現できるかと 思われますが、ACCESSのレポートではそのような機能は存在しますでしょうか? 初歩的な質問で申し訳ありませんが、教えて下さい。 よろしくお願いします。

専門家に質問してみよう