JAva 8ストリーム(Stream API)使用の詳細:フィルタ、スライス、マッピング、検索、マッチング、集約などのストリーム操作
6869 ワード
前編では集合操作の痛み点を紹介し,集合操作のこれらの痛み点がjava 8ストリームAPIの前ではほとんど問題ではないことを発見し,その後ストリームの定義を引き出し,ストリーム操作のタイプ,特徴,およびストリームを使用する基本手順を紹介し,この編ではStream Apiにおける各種ストリーム操作およびいくつかの特殊なストリームの使用について逐一紹介する.
述語でフィルタする
フィルタリングについては,このシリーズの前の文章で何度も登場しているが,ここでは再び以下のように列挙し,完全性を求めた.ベジタリアンメニューを次のコードでフィルタします.
フィルタの重量除去:distinct()関数
重量除去とは、フィルタ結果の重複項目を除去し、fiterの後にdistinct()を呼び出すだけでよい.
ストリームの短縮:limit関数
ショートストリームとは、300カロリー以上のカロリーを取り出した最初の3つの料理など、ストリームからデータの一部を切り取ることです.
スキップ要素:skip(int)関数
スキップ要素とは、ストリームに指定された数の要素をスキップし、残りを操作または取り出します.次のコードのように、300カロリー以上の最初の3つの料理をスキップします.
メニューフローのカロリーが300カロリーより大きい料理が3つ未満の場合、上記のコードは空の
マッピング:map
ストリームのマッピングとは、対流の各要素に指定された関数を適用し、必要な新しい要素にマッピングすることです.メニューからメニュー名のリストをマップした場合、コードは次のとおりです.
メニューストリーム
ストリームのフラット化:flatMap
フローの平坦化操作flatMapは、一般的には複数のフローを1つのフローに統合することである.もし私たちが与えられた単語のリスト[「Hello」,「World]]を重いアルファベットのリスト[「H」,「e」,「l」,「o」,「W」,「r」,「d]]に分割する必要がある場合、どうすればいいですか.
試行1:mapとdistinctの使用
試行1失敗宣言!
試行2:mapとArraysを使用します.stream()
試行2失敗宣言!
試行3:flatMapの使用
试み3成功を告げる!
anyMatch:少なくとも1つの要素を一致させる
メニューにベジタリアンが存在するかどうかを検索し、ベジタリアンに一致すると終了しtrueに戻ります.
allMatch:すべての要素に一致
メニューのすべての料理が健康食品であるかどうかを検査します(熱量が1000未満であれば健康です):
NoneMatch:すべての要素が一致しません
任意の要素を検索:findAny
たとえば、メニュー内のベジタリアン料理を見つけます.
findAnyは、現在のストリームのいずれかの要素を返します.
最初の要素の検索:findFirst()
最初の平方エネルギーが3で割り切れる数を見つけます.
findAnyに比べて、findFirstは並列により多くの制限があり、どの要素を見つけるか気にしない場合はfindAnyを推奨します.
集計操作:reduceを使用して和を求める
帰約操作とは、ストリーム内のすべての要素を繰り返し組み合わせて値を得ることです.たとえば、ストリーム内の要素の合計:
reduceは1つのパラメータのリロード関数のみを受け入れます
違いは戻り値がOptionalになったことです.
帰約操作:reduceを利用して最大と最小値を求める
注意:reduce操作で最も重要なのは、ストリーム内の2つの要素を順次結果として新しい値を生成するためにLambda式またはメソッド参照を指定することです.
述語でフィルタする
フィルタリングについては,このシリーズの前の文章で何度も登場しているが,ここでは再び以下のように列挙し,完全性を求めた.ベジタリアンメニューを次のコードでフィルタします.
List vegetarianMenu = menu.stream()
.filter(Dish::isVegetarian)//
.collect(toList());
フィルタの重量除去:distinct()関数
重量除去とは、フィルタ結果の重複項目を除去し、fiterの後にdistinct()を呼び出すだけでよい.
List numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);
ストリームの短縮:limit関数
ショートストリームとは、300カロリー以上のカロリーを取り出した最初の3つの料理など、ストリームからデータの一部を切り取ることです.
List dishes = menu.stream()
.filter(d -> d.getCalories() > 300)
.limit(3)//
.collect(toList());
スキップ要素:skip(int)関数
スキップ要素とは、ストリームに指定された数の要素をスキップし、残りを操作または取り出します.次のコードのように、300カロリー以上の最初の3つの料理をスキップします.
List dishes = menu.stream()
.filter(d -> d.getCalories() > 300)
.skip(3)// 3
.collect(toList());
メニューフローのカロリーが300カロリーより大きい料理が3つ未満の場合、上記のコードは空の
List
を返します.マッピング:map
ストリームのマッピングとは、対流の各要素に指定された関数を適用し、必要な新しい要素にマッピングすることです.メニューからメニュー名のリストをマップした場合、コードは次のとおりです.
List dishNames = menu.stream()
.map(Dish::getName)//map
.collect(toList());
メニューストリーム
Stream
は、mapマッピング操作Dish::getName
を経て、文字ストリームStream
、すなわち料理名ストリームに変換される.ストリームのフラット化:flatMap
フローの平坦化操作flatMapは、一般的には複数のフローを1つのフローに統合することである.もし私たちが与えられた単語のリスト[「Hello」,「World]]を重いアルファベットのリスト[「H」,「e」,「l」,「o」,「W」,「r」,「d]]に分割する必要がある場合、どうすればいいですか.
試行1:mapとdistinctの使用
// Stream
words.stream()
// Stream,
.map(word -> word.split(""))
// , String[]
.distinct()
// List
.collect(toList());
試行1失敗宣言!
試行2:mapとArraysを使用します.stream()
// Stream
words.stream()
// Stream,
.map(word -> word.split(""))
//Arrays::stream Stream
.map(Arrays::stream)
.distinct()
// List>
.collect(toList());
試行2失敗宣言!
試行3:flatMapの使用
List uniqueCharacters =
// Stream
words.stream()
// Stream,
.map(w -> w.split(""))
//flatMap Stream Stream
.flatMap(Arrays::stream)
//
.distinct()
// List
.collect(Collectors.toList());
试み3成功を告げる!
anyMatch:少なくとも1つの要素を一致させる
メニューにベジタリアンが存在するかどうかを検索し、ベジタリアンに一致すると終了しtrueに戻ります.
if(menu.stream().anyMatch(Dish::isVegetarian)){
System.out.println(" !");
}
allMatch:すべての要素に一致
メニューのすべての料理が健康食品であるかどうかを検査します(熱量が1000未満であれば健康です):
if(menu.stream().allMatch(d -> d.getCalories() < 1000)){
System.out.println(" , 1000");
}
NoneMatch:すべての要素が一致しません
if(menu.stream().noneMatch(d -> d.getCalories() >= 1000)){
System.out.println(" , 1000");
}
任意の要素を検索:findAny
たとえば、メニュー内のベジタリアン料理を見つけます.
Optional dish = menu.stream().filter(Dish::isVegetarian).findAny();
findAnyは、現在のストリームのいずれかの要素を返します.
java.util.Optional
は、Tを包む容器類である、上記のコードのOptional
のように、Dishが装着された容器を理解することができ、このDishは空とすることができ、optionalを通過することができる.get()メソッドはこのコンテナに入っているものを取得し,このシリーズの後の記事ではOptionalクラスの使い方を詳しく紹介する.最初の要素の検索:findFirst()
最初の平方エネルギーが3で割り切れる数を見つけます.
List someNumbers = Arrays.asList(1, 2, 3, 4, 5);
Optional firstSquareDivisibleByThree =
someNumbers.stream()
.map(x -> x * x)
.filter(x -> x % 3 == 0)
.findFirst(); // 9
findAnyに比べて、findFirstは並列により多くの制限があり、どの要素を見つけるか気にしない場合はfindAnyを推奨します.
集計操作:reduceを使用して和を求める
帰約操作とは、ストリーム内のすべての要素を繰り返し組み合わせて値を得ることです.たとえば、ストリーム内の要素の合計:
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
どうして繰り返して組み合わせるのですか?加算帰約動作では、指定された初期値0(reduceメソッドの最初のパラメータ)をストリームの最初の要素に加算し(reduceとして表現された2番目のパラメータBinaryOperatorであり、Lambda式(a,b)->a+bと伝達する)が中間値を得た後、ストリームのすべての要素が加算され、最終的な加算結果が得られるまでストリームの2番目の要素に加算する.reduceは1つのパラメータのリロード関数のみを受け入れます
Optional sum = numbers.stream().reduce((a, b) -> (a + b));
違いは戻り値がOptionalになったことです.
帰約操作:reduceを利用して最大と最小値を求める
//
Optional max = numbers.stream().reduce(Integer::max);
//
Optional min = numbers.stream().reduce(Integer::min);
注意:reduce操作で最も重要なのは、ストリーム内の2つの要素を順次結果として新しい値を生成するためにLambda式またはメソッド参照を指定することです.