連載
» 2005年04月20日 10時00分 UPDATE

JavaTips 〜Javaプログラミング編:オブジェクトを手軽にソートする

[小田原大,@IT]

 オブジェクトや数値型の値の集合をソートするためのメソッドが、配列を扱うjava.util.Arraysのクラスメソッドsortとして用意されています。Arrays.sortは高速なソートアルゴリズムを実装しており、ソートに用いる順序関係(昇順、降順、辞書順など)はインターフェイスjava.util.Comparatorを実装したクラスで自ら定義することができます。

数値の配列をソートする

 int型、double型などの数値型のデータをソートしたいときには、以下のように行います。

int型配列のソート
int[] ia = {10, 5, 30, 20, -18, 0, 50}; // 適当なint型の配列
java.util.Arrays.sort(ia);


 この結果、iaが昇順にソートされます(-18, 0, 5, 10, 20, 30, 50)。iaの中身が書き換えられることに注意してください(sortの戻り値はvoidです)。ソートのアルゴリズムは修正クイックソートが用いられています。クイックソートは最悪の場合(ソート済のデータ)の時間計算量がデータ数nの2乗に比例することが知られていますが、このメソッドではそのような場合にも(n*log n)に比例する時間で実行できる修正がなされています。

オブジェクトをソートする

 単に数値型の配列をソートするのではなく、データをフィールドに持つオブジェクトをソートすることもあります。例えば、String型のフィールドを持つDataクラスを、その文字列長について降順でソートする方法を考えてみます。

リスト1 Data.java
import java.util.*; // ArrayListとComparator
public class Data {
  private String data_;
  public Data(String data){
    data_=data;
  }
  public int length(){
    return data_.length();
  }
  public String toString(){
    return “Data: ”+data_;
  }
  public static void main(String[] args){
    ArrayList al = new ArrayList();
    al.add(new Data(“Atzy”));            // ArrayListにデータを追加
    al.add(new Data(“yuu”));
    al.add(new Data(“Kaneko”));
    al.add(new Data(“ikumi”));
    al.add(new Data(“MI”));
    Object[] oa = al.toArray();            // 配列に変換
    Arrays.sort(oa, new DataComparator()); // DataComparatorで順序関係を指定
    for(int i = 0; i < oa.length; i++){
      // ソート前の配列とソート後の配列を並べて表示
      System.out.println((Data)al.toArray()[i]+”, \t”+(Data)oa[i]);      
    }
  }
}


 Data.javaでString型のデータを持つクラスを定義します。mainメソッドでは、ArraysListに収めた複数のDataオブジェクトをリスト2で定義しているDataComparatorの定める順序関係に従ってソートしています。Comparatorによって「小さい」と判断されるオブジェクトが前に来るようにソートされます。

リスト2 DataComparator.java
 public class DataComparator implements java.util.Comparator{
  public int compare(Object o1, Object o2){
    return ((Data)o2).length() - ((Data)o1).length();
  }
}


 DataComparator.javaはインターフェイスjava.util.Comparatorを実装したクラスです。Comparatorで宣言されているメソッドcompareで順序関係を定義します。compareは2つのオブジェクトを引数に取り、最初の引数が「小さい」ときには負の整数を、「等しい」ときには0を、「大きい」ときには正の整数を返すように実装します。

 上のプログラム例では「Dataオブジェクトが持つStringオブジェクトについて、文字列長が小さい方が大きい」という順序を定義しています。o1の文字列長が3で、o2の文字列長が5なら、compareの戻り値は2となります。これは正の整数なので、o1の方が大きいということになります。

 なお、Comparatorはequalsメソッドも宣言していますが、これはObjectのequalsメソッドによって定義されているため、あえて実装する必要はありません。

実行結果
Data: Atzy,    Data: Kaneko
Data: yuu,     Data: ikumi
Data: Kaneko,  Data: Atzy
Data: ikumi,   Data: yuu
Data: MI,      Data: MI


 実行結果の左列がソート前、右列がソート後を表しています。文字列長の大きいStringを持つDataオブジェクトが前に来るようにソートされたことが分かります。

Profile

WINGSプロジェクト

小田原大


Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

Focus

- PR -

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。