スポンサーサイト





上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

タグ :

   印刷ボタン       この記事に拍手する       このエントリーをはてなブックマークに追加

Return to page top

  • Comments (Close): -
  • TrackBack (Close): -

オブジェクト配列のソート (2)





オブジェクト配列のソート (1)では、ComparableインタフェースのcompareTo()メソッドを使ったソートを学びました。

このやり方では、オブジェクト型の配列の単純なソートをすることはできるのですが、たとえば複数のソート条件を使いたい場合には使えません。

より高度なソートを行うには、Comparatorインタフェースを実装する必要があります。

それではまず、いつものStudentクラスのソートをComparatorインタフェースを使ってやってみましょう。

package kihon;

import java.util.Arrays;
import java.util.Comparator;

class Sample{

public static void main(String args[])
{
Student student[]=new Student[3];
student[0]=new Student(2,"次郎");
student[1]=new Student(3,"三郎");
student[2]=new Student(1,"太郎");

Arrays.sort(student, new StudentComparator());

for(int i=0; i<student.length; i++){
System.out.println("出席番号 "+student[i].num+", 名前 "+student[i].name);
}
}
}

class Student{

int num;
String name;

Student(int num,String name){
this.num=num;
this.name=name;
}
}

class StudentComparator implements Comparator<Student>{
public int compare(Student s1, Student s2){
return s1.num-s2.num;
}
}


Comparableインタフェースがソートしたいオブジェクトのクラス(つまりStudentクラス)に実装するのに対し、Comparatorインタフェースは独自のクラス(今回は StudentComparatorクラス)を定義して実装するという点が大きな違いです。

Comparatorインタフェースにおける compare()メソッドは、Student型の引数を2つもち、両者が比較対象になります。

それではさらに、Comparatorインタフェースのありがたみを味わうために、複数条件によるソートをやってみます。

package kihon;

import java.util.Arrays;
import java.util.Comparator;

class Sample{

public static void main(String args[])
{
Student student[]=new Student[3];
student[0]=new Student(2,"次郎",70);
student[1]=new Student(3,"三郎",70);
student[2]=new Student(1,"太郎",80);

Arrays.sort(student, new StudentComparator());

for(int i=0; i<student.length; i++){
System.out.println("出席番号 "+student[i].num+", 名前 "+student[i].name+", 点数 "+student[i].score);
}
}
}

class Student{

int num;
String name;
int score;

Student(int num,String name,int score){
this.num=num;
this.name=name;
this.score=score;
}
}

class StudentComparator implements Comparator<Student>{
public int compare(Student s1, Student s2){
int cmp=s2.score-s1.score;

if(cmp==0){
cmp=s1.num-s2.num;
}
return cmp;
}
}


StudentComparatorクラスにif文を作って処理を分岐しました。

第一優先が点数の降順、第二優先が出席番号の昇順ですが、これを実現するため変数 cmp を使っています。

つまり、cmpの定義の際には

int cmp=s2.score-s1.score;

と点数の降順とし、if文でcmpが0のとき、つまり点数が同じ生徒について、

cmp=s1.num-s2.num;

と出席番号の昇順としました。



さらに、無名クラスを使って書き替えてみます。

package kihon;

import java.util.Arrays;
import java.util.Comparator;

class Sample{

public static void main(String args[])
{
Student student[]=new Student[3];
student[0]=new Student(2,"次郎",70);
student[1]=new Student(3,"三郎",70);
student[2]=new Student(1,"太郎",80);

Arrays.sort(student, new Comparator<Student>(){
public int compare(Student s1, Student s2){
int cmp=s2.score-s1.score;

if(cmp==0){
cmp=s1.num-s2.num;
}
return cmp;
}
});

for(int i=0; i<student.length; i++){
System.out.println(
"出席番号 "+student[i].num
+", 名前 "+student[i].name
+", 点数 "+student[i].score);
}
}
}

class Student{

int num;
String name;
int score;

Student(int num,String name,int score){
this.num=num;
this.name=name;
this.score=score;
}
}


StudentComparatorクラスというのは、比較の順序だけを定義しただけの、その場限りのクラスです。Arrays.sort()メソッドを実行するときに引数として呼び出されるにすぎません。

無名クラスを使うことで、コードが簡潔になります。また、Comparatorインタフェースがクラス名のように使えるので、比較方法を記述しているのが明確です。

さらに、呼び出した直後にメソッドの中身を記述するので、何をするためにComparatorを呼び出しているのか分かりやすいのではないかと思います。

なお、無名クラスについては 無名クラスとインタフェース を参照。

練習問題 : 上の三人の点数と出席番号による並べ替えのプログラムを、配列ではなくArrayListにデータを格納して並べ替えしてみてください。

解答例

関連記事

タグ :

   印刷ボタン       この記事に拍手する       このエントリーをはてなブックマークに追加

Return to page top

Comments:

Comment Form
Only inform the site author.

Trackback+Pingback:

TrackBack URL for this entry
http://javamania.blog25.fc2.com/tb.php/103-c996fb4a
  • 閉じるボタン
クラスライブラリ解説 目次
クラスライブラリとは
 ├ Java APIの調べ方
 ├ Objectクラスを調べる
 ├ ライブラリのインポート
 ├ 完全修飾クラス名を調べる
 ├ staticインポート
 ├ 外部ライブラリの利用

文字列を扱う
 ├ Stringとイミュータプル
 ├ StringBuilder 文字列の連結
 ├ toString()のオーバーライド
 ├ toXxCase() 大文字と小文字
 ├ compareTo() 値の比較
 ├ parseDouble() 文字を小数値に
 └ 文字列を抜き出す
 ├ char配列からString型へ変換
 ├ 空白文字の除去

日付を扱う
 ├ Calendar 現在の日付
 ├ Date 日付の表示

数値演算を扱う
 ├ round() 切上・切捨・四捨五入
 ├ BigDecimal
 ├ sqrt(),pow() 累乗と平方根
 ├ BigInteger
 ├ int型の最大値・最小値
 ├ random() 乱数作成

ファイルを扱う
 ├ ファイルの存在確認
 ├ ファイルを作成
 ├ ファイルの削除
 ├ ファイルサイズを調べる

入出力ストリーム
 ├ ファイルを読み込む
 ├ 画像ファイルのコピー
 ├ 日本語の読み込みと書き出し
 ├ バッファ入出力
 ├ データ型フリーの出力ストリーム
 ├ getBytes()メソッド

書式つき入出力
 ├ 書式を指定して出力
 ├ 引数インデックス
 ├ 整数値のフォーマット
 ├ 小数値のフォーマット
 ├ 九九の表のフォーマット

例外処理
 ├ printStackTrace()
 ├ NullPointerException
 └ NumberFormatException
月別アーカイブ
カテゴリ
リンク
QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。