2018年4月15日日曜日

[JavaSE8 Goldへの道] その8 ラムダ式を使用したコレクション・ストリームの操作(4)


JavaSE8 Goldへの道(Upgrade to Java SE 8 Programmer 1Z0-810 試験対策)8回目です。

一連の記事は「JavaSE8Gold」ラベルを付けていきます。

今回はストリームのソートです。

sorted()メソッド

その名の通り、ストリームの要素を並べ替えます。

List<String> items = Arrays.asList("xyz", "c", "ac", "fgh", "def");
items.stream()
    .sorted()
    .forEach(System.out::println);

引数なしの場合は自然順序に従ってソートされます。自然順序てなんぞやというと、要はjava.lang.Comparableを実装しているかどうかです。実装していない型のストリームに対してsorted()を呼ぶと、ClassCastExceptionがスローされる可能性があります。・・・とAPIドキュメントに書いてあります。
まあStringとか一般的に使うクラスはみんな実装しているので通常は困らないでしょう。

実行結果
ac
c
def
fgh
xyz


Comparatorによる順序の指定

独自クラスや自分で順序を決めたい場合、java.util.Comparatorを引数に取る方を使います。

例えばこんなEmployeeクラスがあったとして。

public class Employee {
    public String name;

    public Employee(String n) {
        name = n;
    }
}

名前でソートしたい場合、以下のようにします。
Stream.of(new Employee("Char"), new Employee("Amuro"), new Employee("Lalah"), new Employee("Bright"))
            .sorted(Comparator.comparing(e -> e.name))
            .forEach(e -> System.out.println(e.name));

実行結果
Amuro
Bright
Char
Lalah

前回も出てきましたが、 java.util.Comparatorインタフェースにはよく使う比較を得るためのstaticメソッドやdefaultメソッドが定義されているので、大抵は事足ります。
また順序を逆にしたり(reverceOrder())、nullの扱いを変えたり(nullsFirst()/nullsLast())といった操作もあります。

もちろん独自に実装することもできますし、EmployeeクラスにComparableを実装すれば引数無しのsorted()でOKです。

java.lang.Comparablejava.util.Compartorは似てますが間違えないようにしましょう。特に属するパッケージが違います。



複数の条件でソート

複数の条件でソートしたい場合、Comparator#thenComparingメソッドが使えます。
Comparator<Employee> c1 = Comparator.comparing(e -> e.name.length());
Comparator<Employee> c2 = (e1, e2) -> e1.name.compareTo(e2.name);

Stream.of(new Employee("Char"), new Employee("Amuro"), new Employee("Lalah"),
        new Employee("Bright"), new Employee("Fraw"), new Employee("Garma"))
    .sorted(c1.thenComparing(c2))
    .forEach(e -> System.out.println(e.name));

実行結果
Char
Fraw
Amuro
Garma
Lalah
Bright

この例では、名前の文字数順に並べた後に辞書順に並べ替えています。


と、い、う、わ、け、で

今回は短いですがこの辺で。
ソートは配列やコレクションのままでもできますが、ストリームでもできますということで。
何が嬉しいかというとラムダ式が使えるのと、まだ説明していない並列ストリームが使えるのがメリットです。詳しくは続編を待て!

今回も以下のサイトとGoldの通常試験の参考書を参考にしています。
一連の記事は「JavaSE8Gold」ラベルを付けていきます。

それではみなさまよきガジェットライフを(´∀`)ノ


▼こちらの記事もどうぞ

▼ブログを気に入っていただけたらRSS登録をお願いします!
▼ブログランキング参加中!応援よろしくお願いします。

スポンサーリンク