8.0【概要】Stream#mapの使い方でサンプルを作りながらこんな使い方は動だろうかと考えてみたので書いています。基本的には最終的なcollectだったり、reduceだったりを行うため、プリミディブ型に変換することが多くなるのではないかと思います。個人的にStreamの処理を行う最初に処理用のクラスをmapでラップするというやり方が良さそうかなと思いました。複雑な処理をしている例でやってみます。【サンプルの内容】ということでまた売り上げ系のネタです。ある期間の売り上げがあって、そこから条件を満たす売り上げのポイントを算出するというサンプルを作ります。抽出する条件としては春のゲームセール対象売り上げとします。売り上げ金額が3000円以上とします。[データ用クラス]DBにあるデータをORMで変換したことを想定するクラスを作ります。}}ItemTypeには商品種別が入ります。PC、GAME、TOOL、PARTSの四つです。データは下記のように作ります。}真ん中のデータ3つが対象となるデータです。【Streamに直接書く】まずは個人的にあんまり良いコードではないなぁと思うStreamに直接書く方法です。}}パッと見たときに個別の条件や計算はわかりやすいのですが、filter内部が何を意味しているか、collectが何をしているか読み取りにくいです。次にメソッドに分けるやり方です。}先ほどのものよりは見やすいと思います。これで問題はないと思います。【ようやく本題】calculatePoints02のサンプルでわかりやすいコードにはなったと思います。そもそもポイントを計算するメソッドと春のゲームセールをメソッドを同じクラス内で扱ってよいのか?と言うクラス設計的な問題を抱えていると思うのです。ユニットテストするにもcalculatePoints02メソッドを通さないといけないのでやりにくいです。するのかと言うとStreamAPIの処理を行う用のクラスを作成します。今回で言えば、春のゲームセール用の文脈・コンテキスト用のクラスを作成します。}}判定用のメソッドと計算用のメソッドをSampleクラスから持ってきただけです。春のゲームセールスに特化したクラスでクラスの責務としては小さくなっていると思います。テストデータのSalesオブジェクトをわたすだけでユニットテストするのも簡単になりました。}}コードがとてもすっきりしたと思います。最初のmapでSpringGameSalesクラスでラップするよと言うのがなんとなくわかると思います。(実際はわかって欲しいと言う願望です)以降はメソッド参照を使って無駄なパラメータを渡すのを省略しています。SpringGameSales::calculatePoinsのようにラップしたクラスのメソッドを使用しているので文脈も伝わりやすいと思います。(伝わってくれるといいなという願望です。)欠点としては新しくクラスを作成しないといけないことと毎回インスタンスを生成するのでメモリを消費することです。前者に関しては欠点と言うよりはルールがガチガチに決められすぎていると賛同されにくいと言ったところですが。【まとめ】ということでStream#mapでデータ用のクラスをラップする方法を書いてみました。JavaのStreamAPIが公開されたばかりでグッドプラクティス的なものがでてきていはないが現状です。このやり方が良いか悪いかというのはわかりませんが、個人的には良いやり方ではないかなと思います。月別アーカイブはてなブログをはじめよう!gloryofさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。