[解決済み] Java 8: ラムダを改行とインデントでフォーマットする
質問
ラムダインデントで実現したいことは、以下のようなことです。
複数行のステートメント。
String[] ppl = new String[] { "Karen (F)", "Kevin (M)", "Lee (M)", "Joan (F)", "Des (M)", "Rick (M)" };
List<String> strings = Arrays.stream(ppl)
.filter(
(x) ->
{
return x.contains("(M)");
}
).collect(Collectors.toList());
strings.stream().forEach(System.out::println);
一行文です。
List<String> strings = Arrays.stream(ppl)
.map((x) -> x.toUpperCase())
.filter((x) -> x.contains("(M)"))
.collect(Collectors.toList());
現在、Eclipseは以下のように自動整形しています。
複数行のステートメント。
String[] ppl = new String[] { "Karen (F)", "Kevin (M)", "Lee (M)", "Joan (F)", "Des (M)", "Rick (M)" };
List<String> strings = Arrays.stream(ppl).filter((x) ->
{
return x.contains("(M)");
}).collect(Collectors.toList());
strings.stream().forEach(System.out::println);
一行文です。
String[] ppl = new String[] { "Karen (F)", "Kevin (M)", "Lee (M)", "Joan (F)", "Des(M)", "Rick (M)" };
List<String> strings = Arrays.stream(ppl).map((x) -> x.toUpperCase())
.filter((x) -> x.contains("(M)")).collect(Collectors.toList());
strings.stream().forEach(System.out::println);
そして、これは本当に厄介なことだと思います。
collect
の呼び出しの直下に
return
の直下にあり、その間にスペースは全くありません。私は、ラムダをインデントされた新しい行で始められるなら、それが望ましいと思いますし、そうすれば
.filter(
のすぐ上に
.collect(
呼び出しのすぐ上になります。しかし、標準のJava-8 Eclipse Formatterでカスタマイズできるのは、ラムダボディの最初にある中括弧だけです。
()
には何もなく、インデントもありません。
そして一行呼び出しの場合は、基本的なline-wrapを使うだけで、連鎖してしまうのです。これがなぜ後から復号するのが難しいか、説明する必要はないと思います。
どうにかしてフォーマットをもっとカスタマイズして、Eclipse で最初のフォーマットタイプを達成する方法はないでしょうか。(あるいは、オプションとして、IntelliJ IDEA のような別の IDE で。)
EDIT: 私が得ることができた最も近いものは、IntelliJ IDEA 13 Community Edition (read: free edition :P) で、次のものでした (連続したインデントによって定義され、この場合8です)。
public static void main(String[] args)
{
int[] x = new int[] {1, 2, 3, 4, 5, 6, 7};
int sum = Arrays.stream(x)
.map((n) -> n * 5)
.filter((n) -> {
System.out.println("Filtering: " + n);
return n % 3 != 0;
})
.reduce(0, Integer::sum);
List<Integer> list = Arrays.stream(x)
.filter((n) -> n % 2 == 0)
.map((n) -> n * 4)
.boxed()
.collect(Collectors.toList());
list.forEach(System.out::println);
System.out.println(sum);
また、このように連鎖したメソッドの呼び出しを "align"することも可能です。
int sum = Arrays.stream(x)
.map((n) -> n * 5)
.filter((n) -> {
System.out.println("Filtering: " + n);
return n % 3 != 0;
})
.reduce(0, Integer::sum);
List<Integer> list = Arrays.stream(x)
.filter((n) -> n % 2 == 0)
.map((n) -> n * 4)
.boxed()
.collect(Collectors.toList());
list.forEach(System.out::println);
System.out.println(sum);
}
個人的には、より理にかなっている一方で、2番目のバージョンはそれをあまりにも遠くに押しやっているので、私は1番目のバージョンを好みます。
1番目のセットアップを担当するのは、以下のようなものです。
<?xml version="1.0" encoding="UTF-8"?>
<code_scheme name="Zhuinden">
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
<option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" />
<option name="JD_ADD_BLANK_AFTER_RETURN" value="true" />
<option name="JD_P_AT_EMPTY_LINES" value="false" />
<option name="JD_PARAM_DESCRIPTION_ON_NEW_LINE" value="true" />
<option name="WRAP_COMMENTS" value="true" />
<codeStyleSettings language="JAVA">
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="BRACE_STYLE" value="2" />
<option name="CLASS_BRACE_STYLE" value="2" />
<option name="METHOD_BRACE_STYLE" value="2" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="SPACE_WITHIN_BRACES" value="true" />
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_TRY_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SYNCHRONIZED_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="2" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<option name="PARAMETER_ANNOTATION_WRAP" value="1" />
<option name="VARIABLE_ANNOTATION_WRAP" value="1" />
<option name="ENUM_CONSTANTS_WRAP" value="2" />
</codeStyleSettings>
</code_scheme>
すべて合理的であることを確認しようとしましたが、何かを台無しにしてしまったかもしれませんので、微調整が必要かもしれません。
もしあなたが私のようなハンガリー人で、ハンガリー語のレイアウトを使用しているなら、このキーマップは役に立つかもしれません、AltGR+F, AltGR+G, AltGR+B, AltGR+N および AltGR+M (Ctrl+Alt に対応) が使えないということにならないように。
<?xml version="1.0" encoding="UTF-8"?>
<keymap version="1" name="Default copy" parent="$default">
<action id="ExtractMethod">
<keyboard-shortcut first-keystroke="shift control M" />
</action>
<action id="GotoImplementation">
<mouse-shortcut keystroke="control alt button1" />
</action>
<action id="GotoLine">
<keyboard-shortcut first-keystroke="shift control G" />
</action>
<action id="Inline">
<keyboard-shortcut first-keystroke="shift control O" />
</action>
<action id="IntroduceField">
<keyboard-shortcut first-keystroke="shift control D" />
</action>
<action id="Mvc.RunTarget">
<keyboard-shortcut first-keystroke="shift control P" />
</action>
<action id="StructuralSearchPlugin.StructuralReplaceAction" />
<action id="Synchronize">
<keyboard-shortcut first-keystroke="shift control Y" />
</action>
</keymap>
IntelliJはラムダの開始波括弧を改行する方法を提供していないようですが、それ以外はかなり合理的なフォーマット方法なので、これを受理とします。
どのように解決するのですか?
IntelliJ 13をそのまま使えば、おそらくうまくいくでしょう。
このように書くと
// Mulit-Line Statement
String[] ppl = new String[] { "Karen (F)", "Kevin (M)", "Lee (M)", "Joan (F)", "Des (M)", "Rick (M)" };
List<String> strings = Arrays.stream(ppl)
.filter(
(x) ->
{
return x.contains("(M)");
}
).collect(Collectors.toList());
strings.stream().forEach(System.out::println);
そして、オートフォーマッターを適用します(変更なし)。
// Mulit-Line Statement
String[] ppl = new String[]{"Karen (F)", "Kevin (M)", "Lee (M)", "Joan (F)", "Des (M)", "Rick (M)"};
List<String> strings = Arrays.stream(ppl)
.filter(
(x) ->
{
return x.contains("(M)");
}
).collect(Collectors.toList());
strings.stream().forEach(System.out::println);
1行のステートメントでも同じことが言えます。私の経験では、IntelliJは自動書式設定の適用方法においてより柔軟性があります。IntelliJは改行を削除したり追加したりすることはあまりなく、もしそこに置いたなら、そこに置くことを意図しているとみなします。IntelliJは喜んであなたのタブスペースを調整します。
IntelliJはまた、あなたのためにこのうちのいくつかを行うように設定することができます。
設定 - -
「コードスタイル」タブで、「ラップと波括弧」("wrapping and braces") を設定して、メソッド呼び出しを常にラップ(")するようにすることができます。
自動書式化の前
// Mulit-Line Statement
List<String> strings = Arrays.stream(ppl).filter((x) -> { return x.contains("(M)"); }).collect(Collectors.toList());
// Single-Line Statement
List<String> strings = Arrays.stream(ppl).map((x) -> x.toUpperCase()).filter((x) -> x.contains("(M)")).collect(Collectors.toList());
自動整形後
// Mulit-Line Statement
List<String> strings = Arrays.stream(ppl)
.filter((x) -> {
return x.contains("(M)");
})
.collect(Collectors.toList());
// Single-Line Statement
List<String> strings = Arrays.stream(ppl)
.map((x) -> x.toUpperCase())
.filter((x) -> x.contains("(M)"))
.collect(Collectors.toList());
関連
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] Javaで配列を宣言し、初期化する方法は?
-
[解決済み] Java内部クラスと静的ネストされたクラス
-
[解決済み] クロージャ」と「ラムダ」の違いは何ですか?
-
[解決済み] Java 8のmap()メソッドとflatMap()メソッドの違いは何ですか?
-
[解決済み] Distinct() with lambda?
-
[解決済み] Java 8でインデックスを持つストリームを反復処理する簡潔な方法はありますか?
-
[解決済み] Java 8でラムダをパラメータとして受け取るメソッドを定義するにはどうすればよいですか?
-
[解決済み】Java 8 Lambda関数が例外を投げる?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
Eclipse の問題 アクセス制限。タイプ 'jfxrt' はAPI解決されていません。
-
Collections.sortがdoubleでソートできない問題を完璧に解決する。
-
Springの設定でxsdファイルのバージョン番号を設定しない方が良い理由
-
SLF4J: クラス・パスに複数のSLF4Jバインディングが含まれています。
-
java -jarコマンドでパッケージを実行すると、無効または破損したjarfile xxxx.jarが表示される。
-
SocketException java.netの4つの例外解決策。
-
java.sql.SQLException: 結果セットの開始前
-
keytool error: java.io.FileNotFoundException: cacerts (アクセス拒否されました。)
-
ecplise プロンプトが表示されます。"選択したものは起動できません。" "最近の起動はありません。"
-
Java の double データ型における 0.0 と -0.0 の問題