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

 一路向北turbo 发布于 2023-01-04 13:39

我想用lambda缩进实现的目的如下:

多行声明:

String[] ppl = new String[] { "Karen (F)", "Kevin (M)", "Lee (M)", "Joan (F)", "Des (M)", "Rick (M)" };
List strings = Arrays.stream(ppl)
                         .filter(
                             (x) -> 
                             {
                                 return x.contains("(M)");
                             }
                         ).collect(Collectors.toList());
strings.stream().forEach(System.out::println);

单行声明:

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

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

它还允许"对齐"链式方法调用,如下所示:

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

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

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



  

我试图确保一切都合理,但我可能搞砸了,所以可能需要稍作调整.

如果你是像我这样的匈牙利人并且你正在使用匈牙利语布局,那么这个键映射可能对你有用,所以你最终无法使用AltGR + F,AltGR + G,AltGR + B ,AltGR + N和AltGR + M(对应于Ctrl + Alt).



  
    
  
  
    
  
  
    
  
  
    
  
  
    
  
  
    
  
  
  
    
  

虽然IntelliJ似乎没有提供将lambda的开头括号放在一个新行中的方法,否则它是一种相当合理的格式化方法,所以我将其标记为已接受.

6 个回答
  • 在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.

    2023-01-04 13:40 回答
  • 这个问题现在很老了,遗憾的是,Eclipse格式化程序的默认配置仍然不能以可读的方式编写功能代码.

    我尝试了所有其他答案中提到的所有内容,没有人适合大多数用例.
    对某些人来说可能没什么问题,但对其他人来说却不愉快.

    我找到了一种适合我的方式.
    我认为它可以帮助别人,我分享它.

    请注意,我的方式有一个权衡:接受每个合格的调用总是在一个不同的行.
    它可能是格式化程序配置中缺少的选项:根据调用来指示阈值,而不是1默认使用调用.

    以下是我的两个组合工具,可以正确处理它:

    在大多数情况下自定义Eclipse格式化程序配置

    //@formatter:off ... //@formatter:on为角落案例创建代码模板 .


    自定义Eclipse格式化程序配置
    要更改的值在捕获中以红色包围.

    步骤1)创建自己的Java代码样式格式化程序

    Preferences菜单,在树上,去 Java -> Code Style -> Formatter.
    单击"新建"以创建新的Profile(使用"Java约定"初始化它).

    Eclipse格式化程序

    必须在自定义格式化程序配置文件中执行以下两个步骤.

    步骤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屏幕截图中的模板,然后单击"确定".完成!

    模板应用后的结果

    2023-01-04 13:42 回答
  • 开箱即用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());
    

    2023-01-04 13:42 回答
  • 不理想,但你可以关闭那些有点密集的部分格式化.例如

      //@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>代码样式>格式化程序".单击"编辑..."按钮,转到"关/开标签"选项卡并启用标签.

    2023-01-04 13:42 回答
  • 我通过在函数后添加空注释"//"来格式化单行语句.

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

    2023-01-04 13:42 回答
  • Eclipse(Mars)有一个lambda表达式格式化程序选项.

    Window > Preferences > Java > Code Style > Formatter

    在此输入图像描述

    单击Edit按钮,转到Braces标签并将其设置Lambda BodyNext 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
    

    2023-01-04 13:42 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有