Tbpgr Blog

Ruby プログラマ tbpgr(てぃーびー) のブログ

書籍 Effective Java | Comparableの実装を検討する

パンくず

Effective Java
Comparableの実装を検討する

概要

Comparableの実装を検討する

Comparableとは

ComparableインターフェースのcompareToメソッドを実装することで
Arrays.sort,Collections.sort,TreeMap等ソートに関わる処理に対応することができます。

compareToのルール

比較の戻り値は以下のルールを守ること
同値:0
小さい:-1
大きい:1

サンプルコード

Sample12_1Hoge(データクラス。Comparable実装)

package effective.creation.chapter3;

public class Sample12_1Hoge implements Comparable<Sample12_1Hoge> {
  private String name;
  private int age;

  /**
   * @param name
   * @param age
   */
  public Sample12_1Hoge(String name, int age) {
    super();
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  @Override
  public int compareTo(Sample12_1Hoge hoge) {
    int ret = 0;
    ret = this.getName().compareTo(hoge.getName());
    if (ret == 0) {
      if (this.getAge() < hoge.getAge()) {
        return -1;
      } else if (this.getAge() == hoge.getAge()) {
        return 0;
      } else {
        return 1;
      }
    }
    return ret;
  }
}

Sample12_1(ソートの呼び出し)

package effective.creation.chapter3;

import gr.java_conf.tb.tbpg_util.common.CommonUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Sample12_1 {
  public static void main(String[] args) {
    List<Sample12_1Hoge> hoges = new ArrayList<Sample12_1Hoge>();
    hoges.add(new Sample12_1Hoge("tanaka", 12));
    hoges.add(new Sample12_1Hoge("suzuki", 15));
    hoges.add(new Sample12_1Hoge("sato", 22));
    hoges.add(new Sample12_1Hoge("suzuki", 1));

    Collections.sort(hoges);
    for (Sample12_1Hoge hoge : hoges) {
      System.out.println(CommonUtil.getAllFiledInfo(Sample12_1Hoge.class, hoge));
    }
  }
}

出力

class java.lang.String|name|sato
int|age|22
class java.lang.String|name|suzuki
int|age|1
class java.lang.String|name|suzuki
int|age|15
class java.lang.String|name|tanaka
int|age|12

Comparatorと無名クラスによるソートの実現

既に作成済みのクラスに関して、Comparableインターフェースを実装することが不可能な場合
Comparatorを利用することで同等の機能を実現することが可能です。

サンプルコード

Sample12Hoge(Comparableインターフェースを未実装)

package effective.creation.chapter3;

public class Sample12Hoge {
  private String name;
  private int age;

  /**
   * @param name
   * @param age
   */
  public Sample12Hoge(String name, int age) {
    super();
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }
}

Sample12(Comparatorでソート)

package effective.creation.chapter3;

import gr.java_conf.tb.tbpg_util.common.CommonUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Sample12 {
  public static void main(String[] args) {
    List<Sample12Hoge> hoges = new ArrayList<Sample12Hoge>();
    hoges.add(new Sample12Hoge("tanaka", 12));
    hoges.add(new Sample12Hoge("suzuki", 15));
    hoges.add(new Sample12Hoge("sato", 22));
    hoges.add(new Sample12Hoge("suzuki", 1));

    Comparator<Sample12Hoge> hogeComparator = new Comparator<Sample12Hoge>() {
      public int compare(Sample12Hoge hogeOne, Sample12Hoge hogeOther) {
        String namOne = hogeOne.getName();
        String nameOther = hogeOther.getName();
        int ret = 0;
        ret = namOne.compareTo(nameOther);
        if (ret == 0) {
          int ageOne = hogeOne.getAge();
          int ageOther = hogeOther.getAge();
          if (ageOne < ageOther) {
            return -1;
          } else if (ageOne == ageOther) {
            return 0;
          } else {
            return 1;
          }
        }
        return ret;
      }
    };

    Collections.sort(hoges, hogeComparator);
    for (Sample12Hoge hoge : hoges) {
      System.out.println(CommonUtil.getAllFiledInfo(Sample12Hoge.class, hoge));
    }

  }
}

出力

class java.lang.String|name|sato
int|age|22
class java.lang.String|name|suzuki
int|age|1
class java.lang.String|name|suzuki
int|age|15
class java.lang.String|name|tanaka
int|age|12