Java 8:使用换行符和缩进格式化lambda

我想用lambda缩进实现如下:

多线声明:

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之下,而且根本就没有空间。 我更喜欢它,如果我可以开始在一个新的行缩进的lambda,并使.filter(调用将正确的上方.collect(调用。但是,唯一可以使用标准的Java-8 Eclipse格式化器是在lambda体的开头的大括号,但事先没有()括号,也没有缩进。

而在单线电话的情况下,它只是使用基本的换行,使其成为一个链接混乱。 我不认为我需要解释为什么这之后很难解密。

有没有办法以某种方式定制更多的格式,并实现在Eclipse中的第一个格式化types? (或者,也可以在另一个IDE(如IntelliJ IDEA)中)。

编辑:我可以得到最接近IntelliJ IDEA 13社区版(阅读:免费版: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); 

它也允许像这样“alignment”链式方法调用:

  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); } 

我个人发现,虽然它更有意义,但第二个版本太远了,所以我更喜欢第一个。

负责第一个设置的设置如下:

 <?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似乎没有提供将lambda的左括号放在新行中的方法,否则这是一种相当合理的格式化方式,所以我将其标记为已接受。

开箱即用的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); 

你的单行语句也是如此。 根据我的经验,IntelliJ在应用自动格式化方面更加灵活。 IntelliJ不太可能删除或添加行返回,如果你把它放在那里,然后它假设你打算把它放在那里。 IntelliJ会很高兴地为你调整你的标签空间。


IntelliJ也可以configuration为你做一些这个。 在“设置” – >“代码风格” – >“java”下,在“Wrapping and Braces”选项卡中,您可以设置“chain method calls”为“wrap always”。

自动格式化之前

 // 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()); 

在Eclipse中,对于单行语句:

在您的项目或全局首选项中,转到Java -> Code Style -> Formatter -> Edit -> Line Wrapping -> Function Calls -> Qualified Invocations ,设置Wrap all elements, except first if not necessary Force split, even if line shorter than maximum line width

Eclipse(火星)有一个lambdaexpression式格式化程序的选项。

转到Window > Preferences > Java > Code Style > Formatter

在这里输入图像说明

单击Editbutton,转到Braces标签,并将Lambda Body设置为Next Line Indented

在这里输入图像说明

另一种select是将这些属性更新到您的项目设置中。 ( yourWorkspace > yourProject > .settings > org.eclipse.jdt.core.prefs

 org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=next_line_shifted 

我通过在函数之后添加空注释“//”来格式化单行语句。

 List<Integer> list = Arrays.stream(x) // .filter((n) -> n % 2 == 0) // .map((n) -> n * 4) // .boxed() // .collect(Collectors.toList()); 

不是很理想,但是您可以closures格式化程序,使其只是有点密集的部分。 例如

  //@formatter:off int sum = Arrays.stream(x) .map((n) -> n * 5) .filter((n) -> { System.out.println("Filtering: " + n); return n % 3 != 0; }) .reduce(0, Integer::sum); //@formatter:on 

转到“窗口>首选项> Java>代码样式>格式化程序”。 点击“编辑…”button,进入“关/开标签”选项卡并启用标签。