IntelliJ IDEA 2025.3 ヘルプ

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

    The Stream Trace dialog

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

2025 年 5 月 08 日

関連ページ:

JVM ヒープ内のオブジェクトを分析する

デバッグ時に、メモリタブを使用してヒープ内のオブジェクトを確認できます。IntelliJ IDEA を使用すると、個々のクラスインスタンスを追跡し、オブジェクトが生成または保持される条件を分析できます。この情報は、メモリリークとその原因を検出できます。一部のエラーは見落としやすいため、コード検査だけでは手がかりが得られない場合があります。例: 内部クラスによって外部クラスがガベージコレクションの対象にならない場合があり、その結果が発生する可能性があります。このような場合、メモリタブと参照元オブジ...

非同期コードをデバッグする

非同期コードのデバッグは、タスクが 1 つのスレッドでスケジュールされ、別のスレッドで実行されることが多いため、困難です。各スレッドには独自のスタックトレースが存在するため、スレッドの開始前に何が起こったかを把握することが困難です。IntelliJ IDEA は、異なるスレッドのフレーム間の接続を確立することにより、それを容易にします。これにより、ワーカースレッドからタスクがスケジュールされた場所までさかのぼって、実行がすべて同じスレッド内にあるかのようにプログラムをデバッグできます。非同期スタ...