Java 8: Formatting lambda with newlines and indentation

后端 未结 9 1120
[愿得一人]
[愿得一人] 2020-12-12 23:46

What I would like to achieve with lambda indentation is the following:

Multi-line statement:

String[] ppl = new String[] { \"Karen (F)\", \"Kevin (M)         


        
相关标签:
9条回答
  • 2020-12-12 23:47

    In Eclipse, for the single-line statements:

    In your project or global preferences, go to Java -> Code Style -> Formatter -> Edit -> Line Wrapping -> Function Calls -> Qualified Invocations, set Wrap all elements, except first if not necessary and tick Force split, even if line shorter than maximum line width.

    0 讨论(0)
  • 2020-12-12 23:47

    This question is now old and unfortunately, the default configuration of the Eclipse formatter remains still not user-friendly to write functional code in a readable way.

    I tried all things mentioned in all other answers and no one suits for most of use cases.
    It may be fine for some but unpleasant for others.

    I found a way that suits for me the most of the time.
    I share it by thinking that it could help others.

    Note that my way has a trade-off : accepting that each qualified invocation be always on a distinct line.
    It is maybe the missing option in the formatter configuration : indicating the threshold in terms of invocations to wrap the line instead of using 1 invocation by default.

    Here are my 2 combined tools to handle it rather correctly :

    • Customizing Eclipse formatter configuration for most of cases

    • Creating a code template with //@formatter:off ... //@formatter:on for corner cases.


    Customizing Eclipse formatter configuration
    The value to change are surrounded in red in the capture.

    Step 1) Create your own Java Code Style Formatter

    Preferences menu and in the tree, go to Java -> Code Style -> Formatter.
    Click on "New" to create a new Profile (initialize it with "Java conventions").

    The two next steps have to be performed in your custom formatter profile.

    Step 2) Change the indentation configuration for wrapped lines

    The modification allows to use whitespaces instead of tabulations.
    It will matter in the next step as we configure the line wrapping policy with the column indentation option.
    It will avoid indeed creates unpleasant spaces.

    Step 3) Change the default indentation for wrapped lines and the line wrapping policy for qualified invocation


    Here is a test formatting with code of the question.

    Before formatting :

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

    After formatting :

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

    Creating code templates with //@formatter:off ... //@formatter:on for corner cases.

    Writing manually or copy-paste //@formatter:on and //@formatter:off is fine as you write it rarely.
    But if you have to write it several times by week or even worse by day, a more automatic way is welcome.

    Step 1) Go to Java Editor template

    Preferences menu and in the tree, go to Java ->Editor -> Template.

    Step 2) Create template to disable formatting for selected code

    You can now test it.
    Select lines which you want to disable the formatting.
    Now enter ctrl+space twice (first one is "Java proposals" and the second one is "template proposals").
    You should get something like :

    Select the fmt template as in the screenshot and click "Enter". Done!

    0 讨论(0)
  • 2020-12-12 23:48

    I format single-line statement by adding empty comment "//" after functions.

    List<Integer> list = Arrays.stream(x) //
                               .filter((n) -> n % 2 == 0) //
                               .map((n) -> n * 4) //
                               .boxed() //
                               .collect(Collectors.toList());
    
    0 讨论(0)
  • 2020-12-12 23:51

    Not ideal, but you could turn the formatter off for just those sections that are a little dense. For example

      //@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
    

    Go to "Window > Preferences > Java > Code Style > Formatter". Click the "Edit..." button, go to the "Off/On Tags" tab and enable the tags.

    0 讨论(0)
  • 2020-12-12 23:52

    The option that worked for me was ticking the Never join already wrapped lines option in the Line Wrapping section of the Formatter in Preferences.

    0 讨论(0)
  • 2020-12-12 23:56

    If you don’t already have a custom Eclipse formatter:

    Eclipse preferences Java > Code Style > Formatter New Enter a name Click ok Control line breaks

    Edit the profile Line wrapping tab Check “Never join already wrapped lines”

    It will end up like this

        String phrase = employeeList
                .stream()
                .filter(p -> p.getAge() >= 33)
                .map(p -> p.getFirstName())
                .collect(Collectors.joining(" and ", "In Germany ", " are of legal age."));
    

    Need to type every . start in the next line

    credits - https://www.selikoff.net/2017/07/02/eclipse-and-line-wrapping/

    0 讨论(0)
提交回复
热议问题