Java8で追加されたメソッドを使用してコレクション操作を行います。
androidだと、RxJavaとRetrolambdaを使用して同じような事が出来るそうです。
####使用するコレクション
final List<String> names = Arrays.asList("aaa", "bbb1", "bbb2", "c", "d1", "d2", "e");
要素を1つ選択
Optionalを使用することで、このコードを読む人に「結果値が返されない場合がある」ことを明確に示します。
filter()メソッドを使用して、目的のパターンに合致する要素をすべて抜き出し、findFirst()メソッドでコレクションの最初の値を取得します。
public static void pickName (
final List<String> names, final String startingLetter) {
final Optional<String> foundName = names.stream()
.filter(name ->name.startsWith(startingLetter))
.findFirst();
System.out.println(String.format("条件が一致する最初の要素(検索文字:要素) %s: %s",
startingLetter, foundName.orElse("見つかりません")));
}
######Optional
Optionalは、インスタンスが存在しない場合に別の値をセットする使い方の他、値が存在する場合にのみOptionalにラムダ式を実行させることもできます。
foundName.ifPresent(name -> System.out.println("name: "+ name));
コレクションを集約
####合計
mapToInt()メソッドで各要素の文字数を数値に変換し、sum()メソッドで合計します。
System.out.println("コレクションの合計文字数: " +
names.stream()
.mapToInt(name -> name.length())
.sum());
####比較
コレクション内の最も長い名前から、最初の要素が選択されます。
reduce()メソッドは、2つの要素を比較し、その結果を次の要素と比較のために渡すという処理をコレクション内の最後の要素まで繰り返します。
final Optional<String> aLongName = names.stream()
.reduce((name1, name2) -> name1.length() >= name2.length() ? name1 : name2);
aLongName.ifPresent(name -> System.out.println(String.format("最も長い名前: %s", name)));
######その他のメソッド
sum()以外にもmax()、min()、sorted()、average()などの集約用メソッドが用意されています。
要素の結合
大文字に変換し、カンマ区切りで出力します。
map()で変換されたリストでcollect()を呼び出し、Collectorsクラスのjoining()で文字列を結合しています。
System.out.println(
names.stream()
.map(String::toUpperCase)
.collect(joining(", ")));