1. 1〜6 の中の偶数は 2, 4, 6 の 3 個
  2. 空配列なら 0
  3. 奇数しかない配列なら 0
  4. 全部偶数なら配列長と同じ
  5. 0 と負の偶数も偶数として数える
コース一覧
Java 中級:コレクション・Stream・例外処理
filter で絞り込む

Java 中級:コレクション・Stream・例外処理

コレクション、ジェネリクス、例外処理、Stream API、関数型インターフェース、日付処理、ファイル I/O、継承など Java の中級トピックを実践的に学べるコースです。Java の基礎文法とオブジェクト指向を理解している学習者を対象に、現場の Java コードを読み書きするための知識を補強します。約 16 時間 (1 日 30 分 × 32 日) で 64 レッスンを修了でき、修了後は Spring Boot や業務システム開発に必要な Java 力が身につきます。

1
コレクション基礎
01. ArrayList を使う5分
02. List を走査する5分
03. 要素の削除と検索5分
04. HashMap の基本5分
05. Map を走査する5分
06. Set で重複を排除5分
07. Collections クラスの便利メソッド5分
08. コレクション基礎 まとめクイズ5分
2
ジェネリクス
01. ジェネリッククラスを作る5分
02. ジェネリックメソッド5分
03. 境界型パラメータ5分
04. ワイルドカード ?5分
05. Pair<K,V> を作る5分
06. ジェネリクス まとめクイズ5分
3
例外処理
01. try-catch で例外をつかむ5分
02. 複数の catch ブロック5分
03. throws と例外の伝播5分
04. 独自の例外を作る5分
05. try-with-resources5分
06. finally ブロック5分
07. 例外処理 まとめクイズ5分
4
Stream API
01. Stream を作る5分
02. filter で絞り込む5分
03. map で変換する5分
04. reduce で集約する5分
05. collect で集める5分
06. sorted で並び替え5分
07. distinct で重複排除5分
08. limit と skip5分
09. 並列ストリーム5分
10. Stream API まとめクイズ5分
5
関数型インターフェース
01. ラムダ式の基本5分
02. メソッド参照 ::5分
03. Function インターフェース5分
04. Predicate インターフェース5分
05. Consumer と Supplier5分
06. BiFunction と 2 引数の関数5分
07. 関数型インターフェース まとめクイズ5分
6
文字列操作
01. String.format で書式化5分
02. StringBuilder で連結5分
03. 正規表現の基本5分
04. split と join5分
05. 文字列操作 まとめクイズ5分
7
日付と時刻
01. LocalDate で日付を扱う5分
02. LocalDateTime で時刻も扱う5分
03. Duration で時間差を計算5分
04. 日付の書式化とパース5分
05. 日付の加減算5分
06. 日付と時刻 まとめクイズ5分
8
ファイル I/O
01. Files でファイルに書き込む5分
02. ファイルを行単位で読む5分
03. Path でファイルパスを扱う5分
04. BufferedReader と Stream API5分
05. ファイルの存在確認と削除5分
06. ファイル I/O まとめクイズ5分
9
継承とポリモーフィズム
01. extends で継承する5分
02. super で親を呼ぶ5分
03. メソッドのオーバーライド5分
04. abstract で抽象クラス5分
05. interface で契約を定義5分
06. default メソッド5分
07. instanceof と型パターン5分
08. ポリモーフィズムを活かす5分
09. 継承とポリモーフィズム まとめクイズ5分

filter で絞り込む

数えるだけなのに、部品が 4 つ要る

ログの行から ERROR を含む行が何本あるかを数える、というだけの処理を for で書くと次のようになります。

Java

int count = 0; for (String line : logs) { if (line.contains("ERROR")) { count++; } }

カウンタの初期化、ループ、判定の if、そして count++。やりたいことは「ERROR の行を数える」の一言なのに、部品が 4 か所に散らばります。しかも count は途中で書き換わる変数なので、後ろに処理を足すたびに「今いくつ入っているのか」を追いかける羽目になります。

同じ処理を Stream で書くと、こうなります。

Java

long count = logs.stream() .filter(line -> line.contains("ERROR")) .count();

filter が if の役目を、count がカウンタの役目を引き受けています。書く量が減ったこと以上に、上から読むと「ログを流して、ERROR のものだけ残して、数える」とそのまま日本語になるのが利点です。

filter は「通すか、通さないか」だけを決める

filter に渡した line -> line.contains("ERROR") は、要素を 1 つ受け取って true か false を返す式です。Stream を流れてきた要素を 1 つずつこの式にかけて、true になったものだけを次へ通します。false になったものは、そこで捨てられます。

大事なのは、filter が返すのもまた Stream だという点です。つまり filter を書いた時点では、まだ何も起きていません。

Java

logs.stream().filter(line -> line.contains("ERROR"));

これを実行しても、1 行も判定されませんし、画面にも何も出ません。count() のように「ふつうの値」を返すメソッドを最後に呼んだ瞬間に、はじめて全体が動き出します。filter のように Stream を返すものを中間操作、count() のように値を返して打ち止めになるものを終端操作と呼びます。

解説

終端操作を書き忘れて「動かない」と悩むのは、Stream を覚えたての人がほぼ全員 1 度は通る道です。処理が走っていないときは、まず行末を見てください。

元のリストは 1 件も減らない

filter は条件に合わない要素を消しているように見えますが、logs そのものは何も変わりません。通す要素を選んで流しているだけで、元のリストは読んでいるだけです。

Java

List<String> logs = List.of("INFO ok", "ERROR ng", "INFO ok"); long ng = logs.stream().filter(line -> line.contains("ERROR")).count(); System.out.println(logs.size()); // 3 のまま

元のリストを守ったまま別の答えを何通りも取り出せるので、同じデータに対して条件を変えながら何度でも stream() を呼べます。

やってみよう

Solution.evenCount(int[] arr) を完成させて、配列の中の偶数の個数を返してください。

int[] から Stream を作るときは Arrays.stream(arr) または IntStream.of(arr) を使います。あとは通したい要素の条件を filter に渡して、最後に個数を数える終端操作を呼ぶだけです。

型に 1 つだけ注意点があります。個数を数える count() が返すのは long で、このメソッドの戻り値は int です。そのままでは返せないので (int) でキャストしてください。

空配列や、奇数しか入っていない配列を渡したときは 0 が返ります。if で先に長さを調べる必要はありません。要素が 1 つも通らなければ、数えた結果は自然に 0 になります。

要件

  1. Arrays.stream(arr) または IntStream.of(arr) を使って IntStream を作ること
  2. filter にラムダ式を渡して偶数 (n % 2 == 0) だけ残すこと
  3. 終端操作 count() の戻り値 (long) を int にキャストして返すこと

入出力例

evenCount([1,2,3,4,5,6]) → 3 evenCount([]) → 0 evenCount([1,3,5]) → 0 evenCount([2,4,6,8]) → 4 evenCount([0,-2,-3,7,-4]) → 3

ヒント

`Arrays.stream(arr)` は `int[]` を受け取って `IntStream` を返します。`import java.util.Arrays;` を忘れずに

`count()` の戻り値は `long` なので、`return (int) ... .count();` のようにキャストするか `Math.toIntExact` を使います

ラムダ式の中身は `n -> n % 2 == 0` で、偶数のときに `true` を返します。`0` や負の偶数も偶数扱いになります

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • map で変換する

    Stream API の map を使って要素を別の値に変換する書き方を学び、IntStream.map との違いや mapToInt の使い分けまで踏み込んで身につけよう。

  • reduce で集約する

    Stream API の `reduce` を使って配列の要素を 1 つの値に畳み込む方法を学び、整数配列の積を求めるコードを書いてみよう。

  • collect で集める

    Stream の終端操作 collect と Collectors の代表的なファクトリ (toList, toSet, toMap, joining) を学び、filter で絞り込んだ要素を joining で文字列にまとめてみよう。

  • sorted で並び替え

    Stream の sorted() で要素を昇順に並べ替え、Collectors.joining でカンマ区切り文字列に整形するテクニックを身につけよう。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 処理計算や代入を表す長方形
  • カウンタ数を保持して増減する典型 UI
  • ループ繰り返し処理。矢印で戻すか専用記号で示す
  • 変数データに名前をつけて参照する仕組み
  • メソッドクラスに属する関数
  • リスト順序付きで複数の値を扱うデータ構造
  • 配列サイズ固定の同型データの集まり
  • 戻り値呼び出し元への返答を表す点線矢印
main.java
学習モード
エディタを読み込んでいます

メモ

filter で絞り込む

⌘S で保存