今回は、貸出処理などにかかわらず、ページ数などの書籍の情報を表示するメソッドを作成します。
1.変えたところ
Proc.java
2つSysoutしているなかでも、上のほうでは、最も貸し出された書籍を表示します。最初にfilter()で貸し出されたことのある書籍に絞り込んだうえで、貸し出し回数でソートします。
map()はStreamを別のStreamで置き換えるメソッドで、これによってStreamがStream(引数のラムダ式内で書籍名=String型を指定)となります。
findFirst()は、Streamの最初のOptionalを返します。Optionalは値がnullである場合の操作を備えたクラスで、orElseは値がnullである場合は、引数に指定した値を返します。
findFirst()で最も貸し出された書籍を取得し、orElse(値が空でない場合は要素を返し、空である場合は引数に指定した要素を返す)で一冊も書籍が貸し出されていない場合の出力を指定しているというわけです。
下の処理ほうの処理では、Bookオブジェクトからページ数で並べ替えてfindFirst()でページ数が最小の書籍のページ数を取得します。
『こころ』を2回、『想像の共同体』を1回貸し出しして、実際にshowLendInfoAndBookInfo()を呼び出しましょう。
最も貸出された書籍のタイトルは『こころ』です。
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
あれ?
2.そもそもさぁ
StreamはfindFirst()などの終端操作を行うと閉じられてしまい、使いまわしできないようです。一度閉じたStreamを呼び出すとillegalSateExceptionがスローされる。
そもそも「ページ」はint型で管理しているので、わざわざsorted()とかfindFirst()する必要なし。
mapToInt()でIntStream(int型専用のメソッドを備えたクラス)に変換すれば、min()やmax()で最小値/最大値を取得できます。
最も貸出された書籍のタイトルは『こころ』です。
図書館で一番ページが少ない本のページ数は180です。
しかし最大値や最小値、平均などを算出するためにいちいちStreamを作成しなおすのは非常にめんどくさい。
IntSummaryStatistics statistics = stream3.map(r->r.getPages()).collect(Collectors.summarizingInt(s->s));
System.out.println("図書館で一番長い本のページ数は" + statistics.getMax() + "ページです");
System.out.println("図書館で一番短い本のページ数は" + statistics.getMin() + "ページです");
System.out.println("図書館の本の平均ページ数は" + statistics.getAverage() + "ページです");
System.out.println("図書館の本の冊数は" + statistics.getCount() + "冊です");
IntSummaryStatisticsにcollect(Streamで操作した結果を集約するメソッド)で集約した処理結果を渡すと、最大値や最小値などの情報を保存できます。
図書館で一番ページが少ない本のページ数は180です。
図書館で一番長い本のページ数は530ページです
図書館で一番短い本のページ数は180ページです
図書館の本の平均ページ数は331.25ページです
図書館の本の冊数は8冊です
https://gitlab.com/simulacre1/librarytest/-/tree/day1?ref_type=tags