はじめに
最大値・最小値をStream APIを使って取り出そう。というタイトルの通りです。ほとんどサンプルコードになっています。後半はStream APIが導入される前のJavaだとどう書くかなぁ、と思って1.4と5の時代に寄せたサンプルコードも書いています。
サンプルコード
事前の準備
実行用のコードは以下のようなコードを想定しています。
public static void main(String[] args) {
int[] array = {4, 6, 1, 8, 12};
int[] result = getMinMax(array);
System.out.println("最小値: " + result[0] + ", 最大値: " + result[1]);
}
Stream APIを使って最大値・最小値を取得
コード
int[] getMinMax(int[] array) {
int min = Arrays.stream(array).min().getAsInt();
int max = Arrays.stream(array).max().getAsInt();
return new int[]{min, max};
}
IntStreamのメソッドmin()、max()を使って最大値・最小値を取得しています。
- int型の配列をStreamにしているため、Arrays.stream()の戻り値はIntStreamとなります。
- Stream APIでは引数のarrayは変更されません。
- if文やfor文といった制御構文も出現しません。
注意点としては、min(), max(), reduce()の戻り値はOptionalIntであるため、暗黙のキャストができずにコンパイルエラーになります。コードのようにgetAsIntを使うと、有効なint値であればint型を返し、無効な値であれば例外をthrowします。
JavaDoc:OptionalInt.getAsInt()
Javaによる関数型プログラミング Java 8ラムダ式とStream [ ヴェンカット・サブラマニアム ] 価格:2,860円 |
以下、昔話
時代に沿って書いてきます。
Java1.4
基本形のfor文で求めることになるのかな。
int[] getMinMax(int[] array) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < array.length; i++) {
if (array[i] < min) {
min = array[i];
}
if (max < array[i]) {
max = array[i];
}
}
return new int[]{min, max};
}
プログラムを学び始めた方でも、とっつきやすい構文であることは確かかな。
Java 5
拡張for文が追加されたので使ってみようか。というスタイル。
int[] getMinMax(int[] array) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int element : array) {
if (element < min) {
min = element;
}
if (max < element) {
max = element;
}
}
return new int[]{min, max};
}
Java Bronze試験を受けるための学習をしている方はとっつきやすいかも。
for文を使わない(Arraysを使う)
ループなんて使わない。Arraysを使えばいいんだ。という人。
int[] getMinMax(int[] array) {
Arrays.sort(array);
return new int[]{array[0], array[array.length - 1]};
}
ArraysはJava1.2からあるため、配列操作はArraysを使っているところもあるのかもしれないですね。
上述のコードは、配列を昇順ソートして、要素0と要素n – 1を取得することで最小値・最大値の取得をしています。しかし、main関数から渡される引数arrayを変更(破壊)してしまいます。
万が一、呼出元のメソッドで配列の順序を意識してデータ操作している場合、その順序を破壊することになってしまいます。(おそらくあまりないでしょうけど。順序保障を考えるならもうちょっとデータ構造考えた方がいいです。)
最後に
Java18が出ている時代に何を振り返っているんだろう。と考えもしたけれど、こうやって振り返ると最小値・最大値の取得一つとっても可読性があがるなぁと思った。
(Stream APIの事例はmin, maxを別々でとるのでコストはかかっているけれども。)
Java8からStream APIが増えているんだけど、昔ながらのシステムをメンテしていると触れる機会が無かったりするし、アップデートをしたはいいけど、Stream APIがわからない・既存コードがあるからコピペするなどで、書く機会を捨てている可能性もある。
パズルでも脳トレでもいいので、書く機会、見る機会があったら吸収していこう。
コメント