yohhoyの日記

2014-10-07

Comparator with ラムダ式

Java8で機能拡張されたjava.util.Comparator*1インタフェースについてメモ。コンパレータオブジェクトを生成・合成するstatic/defaultメソッドが追加された。

メソッド機能
naturalOrder()(自然順序付け)コンパレータを生成
reverseOrder()(自然順序付け)逆順コンパレータを生成
comparing(e)ソートキー(U型)抽出関数eを指定したコンパレータを生成
comparing(e,u)ソートキー(U型)抽出関数eと(U型)コンパレータuを指定したコンパレータを生成
comparingInt(e)ソートキー(int型)抽出関数eを指定したコンパレータを生成
comparingLong(e)ソートキー(long型)抽出関数eを指定したコンパレータを生成
comparingDouble(e)ソートキー(double型)抽出関数eを指定したコンパレータを生成
c.thenComparing(t)(T型)コンパレータtを追加接続した辞書式順序付けコンパレータを返す
c.thenComparing(e)ソートキー(U型)抽出eを指定した辞書式順序付けコンパレータを返す
c.thenComparing(e,u)ソートキー(U型)抽出関数eと(U型)コンパレータuを指定した辞書式順序付けコンパレータを返す
c.thenComparingInt(e)ソートキー(int型)抽出関数eを指定した辞書式順序付けコンパレータを返す
c.thenComparingLong(e)ソートキー(long型)抽出関数eを指定した辞書式順序付けコンパレータを返す
c.thenComparingDouble(e)ソートキー(double型)抽出関数eを指定した辞書式順序付けコンパレータを返す
nullsFirst(c)nullを最小値とみなすコンパレータを返す
nullsLast(c)nullを最大値とみなすコンパレータを返す
c.reversed()順序反転させたコンパレータを返す

ノート:自然順序(natural order)=java.lang.Comparableインタフェースを実装したクラス、辞書式順序(lexicographic order)=wikipedia:ja:辞書式順序

例1:逆順ソート

// Java8
String[] a = /*...*/;
Arrays.sort(a, Comparator.reverseOrder());
// Java7以前
Arrays.sort(a,
  new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
      return o2.compareTo(o1);
    }
  });

例2:辞書式順序付け

// Java8
class Person {
  //...
  public String getName();
  public String getGender();
  public int getAge();
};
Person[] people = /*...*/;

// Age->Name->Gender の辞書式順序でソート
Arrays.sort(people,
  Comparator.comparingInt(Person::getAge)
            .thenComparing(Person::getName)
            .thenComparing(Person::getGender));
// Java7以前
Arrays.sort(people,
  new Comparator<Person>() {
    @Override
    public int compare(Person o1, Person o2) {
      int ret;
      // NOTE: Integer#compare(int,int)はJava7以降
      ret = Integer.compare(o1.getAge(), o2.getAge());
      if (ret != 0)
        return ret;
      ret = o1.getName().compareTo(o2.getName());
      if (ret != 0)
        return ret;
      return o1.getGender().compareTo(o2.getGender());
    }
  });

例3:null許容

// Java8
class Item {
  //...
  public String getCode();     // 非null保証
  public String getSubCode();  // null許容
};
Item[] items = /*...*/;

// Code->SubCode(nullは最大値) の辞書式順序でソート
Arrays.sort(items,
  Comparator.comparing(Item::getCode)
            .thenComparing(Item::getSubCode,
               Comparator.nullsLast(Comparator.naturalOrder())));
// Java7以前
Arrays.sort(items,
  new Comparator<Item>() {
    @Override
    public int compare(Item o1, Item o2) {
      int ret;
      ret = o1.getCode().compareTo(o2.getCode());
      if (ret != 0)
        return ret;
      String subCode1 = o1.getSubCode();
      String subCode2 = o2.getSubCode();
      if (subCode1 == null) {
        if (subCode2 == null)
          ret = 0;  // null == null
        else
          ret = 1;  // null > o2
      } else {
        if (subCode2 == null)
          ret = -1;  // o1 < null
        else
          ret = subCode1.compareTo(subCode2);
      }
      return ret;
    }
  });

関連URL

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/yohhoy/20141007/p1
リンク元