100本ノック
Java Gold(SE 11/17/21)の試験対策において、Stream APIは最も配点が高く、かつ「ひっかけ問題」が作りやすい最重要分野です。
100本すべてをコードで書くと膨大になるため、**試験に出る「急所」を100個のチェックリスト(逆引きリファレンス)**にまとめました。これらをすべて理解していれば、Stream問題は満点が狙えます。
1. Streamの生成(1-15)¶
Stream.of(1, 2, 3):可変引数から生成list.stream():Collectionから生成Arrays.stream(array):配列から生成Stream.empty():空のStreamStream.iterate(0, n -> n + 2):無限Stream(シード値と関数)Stream.iterate(0, n -> n < 10, n -> n + 2):Java 9以降の有限iterateStream.generate(Math::random):無限Stream(Supplierを使用)IntStream.range(1, 5):1, 2, 3, 4 (5を含まない)IntStream.rangeClosed(1, 5):1, 2, 3, 4, 5 (5を含む)String.chars():文字列をIntStreamに変換Files.lines(path):ファイル各行のStreamRandom.ints():乱数のIntStreamStream.builder().add(1).build():BuilderパターンStream.concat(s1, s2):2つのStreamの連結-
Collection.parallelStream():並列Streamの生成2. 中間操作:基本(16-30)¶
-
filter(Predicate):条件一致のみ map(Function):型の変換、値の加工distinct():重複排除(equals()とhashCode()を使用)sorted():自然順序でソートsorted(Comparator):カスタムソートpeek(Consumer):デバッグ用。要素を変更せず処理を通すlimit(long):先頭からn個に制限(短絡評価)skip(long):先頭からn個を捨てるflatMap(Function<T, Stream<R>>):1対多の展開・平坦化mapToInt/mapToLong/mapToDouble:プリミティブStreamへの変換boxed():プリミティブStreamからラッパー型StreamへasDoubleStream():IntStreamなどをDoubleStreamへmapToObj(IntFunction):プリミティブからオブジェクトへtakeWhile(Predicate):条件を満たさなくなった時点で終了 (Java 9+)-
dropWhile(Predicate):条件を満たす間は捨て、その後を維持 (Java 9+)3. 終端操作:基本(31-45)¶
-
forEach(Consumer):順次処理 forEachOrdered(Consumer):並列でも順序を維持して処理toArray():Object配列を返すtoArray(IntFunction):特定の型(String[]::new等)の配列reduce(BinaryOperator):1つの値に集約(Optionalを返す)reduce(identity, BinaryOperator):初期値あり集約(値を返す)collect(Collector):List, Set, Mapなどへ変換min(Comparator)/max(Comparator):最小・最大count():要素数(long型)anyMatch(Predicate):どれか1つでも一致するか(短絡評価)allMatch(Predicate):すべて一致するか(短絡評価)noneMatch(Predicate):1つも一致しないか(短絡評価)findFirst():最初の要素(Optional)findAny():どれか1つの要素(Optional。並列で効果的)-
iterator():StreamからIteratorを得る4. Collectorsクラス(46-65)¶
-
toList()/toUnmodifiableList()(Java 16+) toSet()/toUnmodifiableSet()toCollection(ArrayList::new):特定の具象クラスへtoMap(keyMapper, valueMapper)toMap(key, value, mergeFunction):キー重複時の処理を指定joining():文字列連結joining(","):デリミタ付き連結joining(",", "[", "]"):接頭辞・接尾辞付きsummingInt(ToIntFunction):合計averagingInt(ToIntFunction):平均summarizingInt(ToIntFunction):統計情報(IntSummaryStatistics)counting():要素数minBy(Comparator)/maxBy(Comparator)groupingBy(Function):Map>にグループ化 groupingBy(Function, Collector):下流(downstream)コレクタを指定partitioningBy(Predicate):true/falseの2つに分割mapping(Function, Collector):集計中に型変換filtering(Predicate, Collector):集計中にフィルタ (Java 9+)flatMapping(Function, Collector):集計中に平坦化 (Java 9+)-
collectingAndThen(Collector, Function):集計後に別の型に変換5. 並列Streamの挙動(66-75)¶
-
parallel():中間操作で並列化 sequential():順次処理に戻すisParallel():並列かどうか確認unordered():順序の制約を外す(並列化の高速化)reduceにおける第3引数:並列時の結合器(Combiner)identityの性質:op(identity, x) == xである必要性- 並列時の
findFirstvsfindAny - 並列時の副作用:
forEach内での外部変数操作はNG Spliterator:Streamの分割用イテレータ-
ステートフル中間操作(
sorted,distinct)の並列負荷6. Optionalの連携(76-85)¶
-
Optional.ofNullable(val) ifPresent(Consumer)ifPresentOrElse(Consumer, Runnable)(Java 9+)orElse(T):デフォルト値orElseGet(Supplier):遅延評価のデフォルト値orElseThrow():例外を投げるfilter(Predicate):Optional内の値をフィルタmap(Function):Optional内の値を変換flatMap(Function):Optionalを返す関数と連結-
stream():OptionalをStreamに変換 (Java 9+)7. 試験で狙われる特殊仕様・ひっかけ(86-100)¶
-
Streamの再利用不可:一度終端操作を呼ぶとIllegalStateException
- 遅延評価:終端操作を呼ばないと中間操作は実行されない
- プリミティブStreamの専用メソッド:
sum(),average(),summaryStatistics() - 関数型インターフェースの使い分け:
Predicate,Function,Consumer,Supplier - Comparatorの合成:
reversed(),thenComparing() - 空のStreamに対する終端操作:
countは0、allMatchはtrue、anyMatchはfalse - nullを含むStream:
sorted()などでNullPointerException - 無限Streamの終端操作:
limitなしでsortedやcollectを呼ぶと停止しない - flatMapの戻り値:Streamである必要がある(Collectionではない)
- バイナリ演算:
reduce(0, (a, b) -> a + b) - 副作用の禁止:Stream外の変数を書き換えない
- peekは要素を捨てない:あくまでデバッグ・監視用
- IntStreamの
max()はOptionalIntを返す - toMapの第3引数がない場合:キー重複で例外が発生する
- Stream.of(array) vs Arrays.stream(array):プリミティブ配列時の挙動の違い
学習アドバイス¶
Java Gold試験では、「このコードを実行するとどうなるか?」という問題が出ます。 特に 「39. count()」のような終端操作がないために何も出力されない というひっかけや、「86. Streamの再利用」による例外 は頻出です。
この100項目の中で、コード例を見てみたい特定の番号はありますか?詳しく解説します。