IntelliJ IDEA 2026.1 Help

Java Stream 操作を分析する

Java ストリームはデバッグが難しい場合があります。 これは、Java ストリームがバックグラウンドで処理ロジックを処理するため、特定の値がどのように導出されるかのトレースが複雑になる可能性があるためです。 Java ストリームのデバッグを支援するために、IntelliJ IDEA は Java ストリーム内で何が起こっているかを視覚化します。

関数スタイルで書かれた簡単なプログラムを取り上げて、関数がどのように機能するかを示しましょう。

import java.util.stream.IntStream; class PrimeFinder { static int skip = 0; static int limit = 100; public static void main(String[] args) { if (args.length >= 1) skip = Integer.parseInt(args[0]); if (args.length >= 2) limit = Integer.parseInt(args[1]); IntStream.iterate(1, n -> n + 1) .skip(skip) .limit(limit) .filter(PrimeTest::isPrime) .forEach(System.out::println); } } class PrimeTest { static boolean isPrime(int candidate) { return candidate == 91 || // a bug here IntStream.rangeClosed(2, (int) Math.sqrt(candidate)) .noneMatch(n -> (candidate % n == 0)); } }

クラス名が示すように、このアプリは素数を見つけます。 プログラム引数を使用して、開始数とチェックする候補の数を指定できます。 チェックロジックは、Java 8 ストリームによって処理されます。

プログラムの出力を見ると、そこに余分な数字があります。

79 83 89 91 <- extra 97

これらの誤った数値がどこから来ているのかを理解するために、ストリームデバッガー機能を使用しましょう。

  1. ストリームが使用されている行でプログラムを中断します。 これには、ターミナル操作を含む任意のストリーム操作を使用できます。

    public static void main(String[] args) { if (args.length >= 1) skip = Integer.parseInt(args[0]); if (args.length >= 2) limit = Integer.parseInt(args[1]); IntStream.iterate(1, n -> n + 1) // set breakpoint here .skip(skip) .limit(limit) .filter(PrimeTest::isPrime) .forEach(System.out::println); }
  2. デバッグ ツールウィンドウのツールバーで、 詳細 More button をクリックし、 現在のストリームチェーンをトレース Trace Current Stream Chain button を選択します。

  3. ストリームトレース ダイアログを使用して、ストリーム内の操作を分析します。 上部のタブでは、特定の操作を切り替えて、各操作で値がどのように変換されるかを確認できます。

    ストリームトレースダイアログ

ストリームを調査すると、追加の値は filter 操作から来ていることがわかります。 バグの検索は、 filter述語 、より具体的には PrimeTest.isPrime() メソッドに絞り込まれました。

2026 年 3 月 30 日