連載
» 2014年05月20日 18時00分 公開

Java 8はラムダ式でここまで変わる(4):Stream APIの主なメソッドと処理結果のOptionalクラスの使い方 (4/4)

[長谷川智之,株式会社ビーブレイクシステムズ]
前のページへ 1|2|3|4       

要素を判定するメソッド

 次はStreamの要素を判定するメソッドを見てみましょう。以下は、主なものです。

戻り値 メソッド 概要
boolean allMatch(Predicate<? super T> predicate) Streamの全ての要素がpredicateの判定でTrueを返す場合、戻り値としてTrueを返す
boolean anyMatch(Predicate<? super T> predicate) Streamの要素のどれかがpredicateの判定でTrueを返す場合、戻り値としてTrueを返す
boolean noneMatch(Predicate<? super T> predicate) Streamの要素がどれもpredicateの判定でTrueを返さない場合、戻り値としてTrueを返す
List<BigDecimal> list = new ArrayList<>();
list.add(new BigDecimal(1));
list.add(new BigDecimal(2));
list.add(new BigDecimal(3));
// 要素の全てが0より大きければTrue
boolean allMatch = list.stream().allMatch(value -> value.compareTo(BigDecimal.ZERO) > 0);
System.out.println("allMatch: " + allMatch);
// 要素のどれかが3と等しければTrue
boolean anyMatch = list.stream().anyMatch(value -> value.compareTo(new BigDecimal(3)) == 0);
System.out.println("anyMatch: " + anyMatch);
// 要素の中に0未満のものが1つも含まれないならTrue
boolean noneMatch = list.stream().noneMatch(value -> value.compareTo(BigDecimal.ZERO) < 0);
System.out.println("noneMatch: " + noneMatch);
// 要素の全てが1より大きければTrue
boolean allMatch2 = list.stream().allMatch(value -> value.compareTo(BigDecimal.ONE) > 0);
System.out.println("allMatch2: " + allMatch2);
// 要素のどれかが0と等しければTrue
boolean anyMatch2 = list.stream().anyMatch(value -> value.compareTo(BigDecimal.ZERO) == 0);
System.out.println("anyMatch2: " + anyMatch2);
// 要素の中に1以下のものが1つも含まれないならTrue
boolean noneMatch2 = list.stream().noneMatch(value -> value.compareTo(BigDecimal.ONE) <= 0);
System.out.println("noneMatch2: " + noneMatch2);
サンプル
allMatch: true
anyMatch: true
noneMatch: true
allMatch2: false
anyMatch2: false
noneMatch2: false
実行結果

Streamが持つ要素数を返すメソッド

 次はStreamの要素数を返すメソッドを見てみましょう。

戻り値 メソッド 概要
long count() Streamが持つ要素の個数を返す
List<BigDecimal> list = new ArrayList<>();
list.add(new BigDecimal(1));
list.add(new BigDecimal(2));
list.add(new BigDecimal(3));
long count = list.stream().count();
System.out.println("count: " + count);
サンプル
count: 3
実行結果

数値の集計を行うメソッド

 Streamから拡張されたプリミティブな数値の要素を持つStream(IntStream、LongStream、DoubleStream)では次の集計結果を返すメソッドがあります。

戻り値 メソッド 概要
int / long /double sum() Streamが持つ要素の合計を返す。戻り値はそのStreamが表すものになる。要素がない場合は0を返す
OptionalDouble average() 平均値を返す。要素がない場合はEmptyなOptionalDoubleを返す。割り切れない場合はdouble値で表現できる値に丸められる
List<BigDecimal> list = new ArrayList<>();
list.add(new BigDecimal(1));
list.add(new BigDecimal(2));
list.add(new BigDecimal(3));
int[] intValues = {1, 2, 3};
long[] longValues = {1L, 2L, 3L};
double[] dblValues = {0.1, 0.2, 0.3};
System.out.println("----- sumメソッド -----");
IntStream intStream = Arrays.stream(intValues);
int intSumResult = intStream.sum();
System.out.println("intStream.sum(): " + intSumResult);
LongStream longStream = Arrays.stream(longValues);
long longSumResult = longStream.sum();
System.out.println("longStream.sum(): " + longSumResult);
DoubleStream doubleStream = Arrays.stream(dblValues);
double doubleSumResult = doubleStream.sum();
System.out.println("doubleStream.sum(): " + doubleSumResult);
System.out.println("----- averageメソッド -----");
System.out.println("Arrays.stream(intValues).average(): " + Arrays.stream(intValues).average());
System.out.println("Arrays.stream(longValues).average(): " + Arrays.stream(longValues).average());
System.out.println("Arrays.stream(dblValues).average(): " + Arrays.stream(dblValues).average());
サンプル
----- sumメソッド -----
intStream.sum(): 6
longStream.sum(): 6
doubleStream.sum(): 0.6
----- averageメソッド -----
Arrays.stream(intValues).average(): OptionalDouble[2.0]
Arrays.stream(longValues).average(): OptionalDouble[2.0]
Arrays.stream(dblValues).average(): OptionalDouble[0.19999999999999998]
実行結果

 この実行結果から分かる通り、double値で計算する場合、2進数と10進数での変換時の誤差が発生するので注意してください(※sumメソッドでも、例えば「double[] dblValues = {0.1, 0.7, 0.3};」とした場合、意図した結果になりません)。

要素を配列として返すメソッド

 次はStreamが持っている要素を配列にして返すメソッドを見てみましょう。

戻り値 メソッド 概要
Object[] toArray() Streamが持つ要素をObjectの配列にして返す
T[] toArray(IntFunction<T[]> intFunction) intFunctionの引数にStreamが持つ要素数を渡しStream が持つ要素のTの型の配列にして返す
String[] values = {"あ", "い", "う", "え", "お"};
System.out.println("----- toArray() -----");
Stream<String> stream = Arrays.stream(values);
Object[] objects = stream.toArray();
for (Object result : objects) {
    System.out.println("toArray(): " + result);
}
System.out.println("----- toArray(IntFunction<T[]>) -----");
Stream<String> stream2 = Arrays.stream(values);
String[] strings = stream2.toArray(count -> {
    System.out.println("count=" + count);
    return new String[count];
});
for (String result : strings) {
    System.out.println("toArray(IntFunction): " + result);
}
サンプル
----- toArray() -----
toArray(): あ
toArray(): い
toArray(): う
toArray(): え
toArray(): お
----- toArray(IntFunction<T[]>) -----
count=5
toArray(IntFunction): あ
toArray(IntFunction): い
toArray(IntFunction): う
toArray(IntFunction): え
toArray(IntFunction): お
実行結果

次回は、ラムダ式と関連の深いメソッド参照とコンストラクタ参照

 今回はJava 8の新機能であるStream APIの主なメソッドについて見てきました。サンプルを見て分かるように、ラムダ式を使うことによってStream APIの関数型インターフェースの実装を簡潔にできるようなっています。

 次回は、さらに今回紹介しきれなかったStream APIのその他のメソッド、およびラムダ式と関連の深いメソッド参照とコンストラクタ参照を見ていきます。ご期待ください。

著者プロフィール

長谷川 智之(はせがわ ともゆき)

株式会社ビーブレイクシステムズ開発部所属。

社内サークル執筆チーム在籍。

主な執筆。

@IT連載『Javaの常識を変えるPlay framework入門

日経ソフトウェア連載『コツコツ学ぶAndroidネイティブアプリ開発教室』


前のページへ 1|2|3|4       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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