我想用lambda缩进实现的目的如下:
多行声明:
String[] ppl = new String[] { "Karen (F)", "Kevin (M)", "Lee (M)", "Joan (F)", "Des (M)", "Rick (M)" }; Liststrings = Arrays.stream(ppl) .filter( (x) -> { return x.contains("(M)"); } ).collect(Collectors.toList()); strings.stream().forEach(System.out::println);
单行声明:
Liststrings = 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)" }; Liststrings = 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)" }; Liststrings = 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 Formatter定制的东西是lambda主体开头的大括号,但()
事先没有括号,也没有缩进.
在单行调用的情况下,它只使用基本的换行并使其成为链式混乱.我认为我不需要解释为什么之后很难解密.
有没有办法以某种方式更多地自定义格式并在Eclipse中实现第一种格式化类型?(或者,可选地,在另一个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); Listlist = 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);
它还允许"对齐"链式方法调用,如下所示:
int sum = Arrays.stream(x) .map((n) -> n * 5) .filter((n) -> { System.out.println("Filtering: " + n); return n % 3 != 0; }) .reduce(0, Integer::sum); Listlist = 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); }
我个人发现虽然它更有意义,但第二个版本推动它太远了,所以我更喜欢第一个版本.
负责第一次设置的设置如下:
我试图确保一切都合理,但我可能搞砸了,所以可能需要稍作调整.
如果你是像我这样的匈牙利人并且你正在使用匈牙利语布局,那么这个键映射可能对你有用,所以你最终无法使用AltGR + F,AltGR + G,AltGR + B ,AltGR + N和AltGR + M(对应于Ctrl + Alt).
虽然IntelliJ似乎没有提供将lambda的开头括号放在一个新行中的方法,否则它是一种相当合理的格式化方法,所以我将其标记为已接受.
在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格式化程序的默认配置仍然不能以可读的方式编写功能代码.
我尝试了所有其他答案中提到的所有内容,没有人适合大多数用例.
对某些人来说可能没什么问题,但对其他人来说却不愉快.
我找到了一种适合我的方式.
我认为它可以帮助别人,我分享它.
请注意,我的方式有一个权衡:接受每个合格的调用总是在一个不同的行.
它可能是格式化程序配置中缺少的选项:根据调用来指示阈值,而不是1
默认使用调用.
以下是我的两个组合工具,可以正确处理它:
在大多数情况下自定义Eclipse格式化程序配置
//@formatter:off ... //@formatter:on
为角落案例创建代码模板 .
自定义Eclipse格式化程序配置
要更改的值在捕获中以红色包围.
步骤1)创建自己的Java代码样式格式化程序
Preferences
菜单,在树上,去 Java -> Code Style -> Formatter
.
单击"新建"以创建新的Profile
(使用"Java约定"初始化它).
必须在自定义格式化程序配置文件中执行以下两个步骤.
步骤2)更改包装线的缩进配置
修改允许使用空格而不是制表.
在我们使用列缩进选项配置换行策略时,下一步将很重要.
它将避免确实产生令人不快的空间.
步骤3)更改包装行的默认缩进和限定调用的换行策略
这是一个测试格式与问题的代码.
格式化之前:
void multiLineStatements() { 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); } void singleLineStatements() { 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); }
格式化后:
void multiLineStatements() { 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); } void singleLineStatements() { 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); }
//@formatter:off ... //@formatter:on
为角点案例创建代码模板 .
手动编写或复制粘贴//@formatter:on
,//@formatter:off
很少写.
但是,如果你必须按周写几次,甚至白天写一次,那么欢迎采用更自动的方式.
步骤1)转到Java编辑器模板
Preferences
菜单,在树上,去 Java ->Editor -> Template
.
步骤2)创建模板以禁用所选代码的格式
你现在可以测试它.
选择要禁用格式的行.
现在输入ctrl+space
两次(第一个是"Java提案",第二个是"模板提案").
你应该得到类似的东西:
选择fmt
屏幕截图中的模板,然后单击"确定".完成!
开箱即用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还可以配置为您执行此操作.在"设置" - >"代码样式" - >"java"下,在"环绕和括号"选项卡中,您可以将"链式方法调用"设置为"始终包装".
在自动格式化之前
// 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());
不理想,但你可以关闭那些有点密集的部分格式化.例如
//@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>代码样式>格式化程序".单击"编辑..."按钮,转到"关/开标签"选项卡并启用标签.
我通过在函数后添加空注释"//"来格式化单行语句.
List<Integer> list = Arrays.stream(x) // .filter((n) -> n % 2 == 0) // .map((n) -> n * 4) // .boxed() // .collect(Collectors.toList());
Eclipse(Mars)有一个lambda表达式格式化程序选项.
去 Window > Preferences > Java > Code Style > Formatter
单击Edit
按钮,转到Braces
标签并将其设置Lambda Body
为Next Line Indented
另一个选项是将这些属性更新到项目设置中.(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