[解決済み] ラムダ式でstream().map(...)をデバッグするには?
質問
私たちのプロジェクトでは、java 8に移行しており、その新機能をテストしています。
私のプロジェクトでは、Guavaの述語と関数を使って、いくつかのコレクションをフィルタリングし、変換しています。
Collections2.transform
と
Collections2.filter
.
この移行では、例えばguavaのコードをjava 8の変更に変更する必要があります。だから、私がやっている変更は、一種のものです。
List<Integer> naturals = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10,11,12,13);
Function <Integer, Integer> duplicate = new Function<Integer, Integer>(){
@Override
public Integer apply(Integer n)
{
return n * 2;
}
};
Collection result = Collections2.transform(naturals, duplicate);
に...
List<Integer> result2 = naturals.stream()
.map(n -> n * 2)
.collect(Collectors.toList());
guava を使用すると、各変換処理をデバッグできるので、コードのデバッグが非常に楽になります。しかし、私の懸念は、例えば、次のようなコードをどのようにデバッグするかということです。
.map(n -> n*2)
.
デバッガを使うと、次のようなコードが表示されます。
@Hidden
@DontInline
/** Interpretively invoke this form on the given arguments. */
Object interpretWithArguments(Object... argumentValues) throws Throwable {
if (TRACE_INTERPRETER)
return interpretWithArgumentsTracing(argumentValues);
checkInvocationCounter();
assert(arityCheck(argumentValues));
Object[] values = Arrays.copyOf(argumentValues, names.length);
for (int i = argumentValues.length; i < values.length; i++) {
values[i] = interpretName(names[i], values);
}
return (result < 0) ? null : values[result];
}
しかし、Guavaのようにコードをデバッグするのが簡単ではありません。
n * 2
変換を見つけることができませんでした。
この変換を見る方法、またはこのコードを簡単にデバッグする方法はありますか?
編集:私は別のコメントから答えを追加し、答えを投稿しました。
ありがとうございます。
Holger
のコメントで私の質問に答えてくれたおかげで、ラムダブロックを持つアプローチによって変換プロセスを見ることができ、ラムダボディの中で何が起こったかをデバッグすることができました。
.map(
n -> {
Integer nr = n * 2;
return nr;
}
)
おかげさまで
Stuart Marks
のおかげで、メソッド参照を持つというアプローチは、変換処理をデバッグすることも可能にしました。
static int timesTwo(int n) {
Integer result = n * 2;
return result;
}
...
List<Integer> result2 = naturals.stream()
.map(Java8Test::timesTwo)
.collect(Collectors.toList());
...
おかげさまで
Marlon Bernardes
の回答で、私のEclipseが表示すべきものを表示しないことに気づき、peek()の使用により結果を表示することができました。
どのように解決するのですか?
EclipseやIntelliJ IDEAを使いながらラムダ式をデバッグするのは、通常、問題ないでしょう。ブレークポイントを設定し、ラムダ式全体を検査しないように注意してください (ラムダ本体のみを検査します)。
別のアプローチとして
peek
を使ってストリームの要素を検査することです。
List<Integer> naturals = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13);
naturals.stream()
.map(n -> n * 2)
.peek(System.out::println)
.collect(Collectors.toList());
UPDATEです。
あなたが混乱しているのは
map
は
intermediate operation
- の後にのみ実行される遅延操作です。
terminal operation
が実行された後にのみ実行される遅延操作である。ですから、あなたが
stream.map(n -> n * 2)
を呼び出したとき、ラムダ本体は現時点では実行されていないのです。ブレークポイントを設定し、端末操作が呼ばれた後に検査する必要があります (
collect
が呼ばれた後、ブレークポイントを設定して検査する必要があります(この場合)。
確認 ストリーム操作 を参照してください。
UPDATE 2:
引用元 ホルガーの のコメントを引用しています。
<ブロッククオートここで厄介なのは、mapの呼び出しとラムダ式が1つの行にあることです。 式が 1 行に存在するため、ブレークポイントが 2 つの全く関連性のない動作で停止してしまうことです。 で止まってしまうことです。
の直後に改行を挿入すると
map(
の直後に改行を入れると、ラムダ式だけのブレークポイントを設定することができます。
また、デバッガが中間値を表示しないのは珍しいことではなく
a
return
文の中間値を表示しないことも珍しくありません。ラムダを変更することで
n -> { int result=n * 2; return result; }
に変更すると、結果を検査することができます。ここでも改行が必要です。
行ごとにステップする場合は適切に改行すること...
関連
-
jd-gui Java Exceptionが発生しました。
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] Mavenを使用して、依存関係を持つ実行可能なJARを作成するにはどうすればよいですか?
-
[解決済み] Node.jsアプリケーションをデバッグするにはどうすればよいですか?
-
[解決済み] Java 8 StreamをArrayに変換する方法は?
-
[解決済み] Distinct() with lambda?
-
[解決済み] スタックトレースとは何ですか、またアプリケーションのエラーをデバッグするためにスタックトレースをどのように使用できますか?
-
[解決済み] IteratorをStreamに変換するには?
-
[解決済み] Java 8でラムダをパラメータとして受け取るメソッドを定義するにはどうすればよいですか?
-
[解決済み】静的なMapを初期化する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java エラー報告 スレッド "main" での例外 java.util.NoSuchElementException
-
jd-gui Java Exceptionが発生しました。
-
eclipse アクセス制限です。タイプ 'xxx' は API ではありません(必須ライブラリ '' の制限)。
-
Spring Boot による HTTPS アクセスの設定
-
java Mail send email smtp is not authenticated by TLS encryption solution.
-
Eclipseプロンプトを実行する java仮想マシンを使用しない
-
Spring boot runs with Error creating bean with name 'entityManagerFactory' defined in class path resource
-
スレッド "main" で例外発生 java.lang.ArrayIndexOutOfBoundsException: 0 at One1.main(One1.java:3)
-
javaでよく使われる英単語
-
SocketTimeoutExceptionです。読み込みがタイムアウトしました