program story

자바 8 : 줄 바꿈 및 들여 쓰기로 람다 서식 지정

inputbox 2020. 10. 24. 10:13
반응형

자바 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로 사용자 정의 할 수있는 유일한 것은 람다 본문의 시작 부분에있는 중괄호이지만 ()사전에 대괄호 나 들여 쓰기를 위한 것은 없습니다 .

그리고 단일 회선 호출의 경우 기본 줄 바꿈을 사용하여 체인이 엉망이됩니다. 나중에 이것이 왜 해독하기 어려운지 설명 할 필요가 없다고 생각합니다.

어떻게 든 형식을 사용자 정의하고 Eclipse에서 첫 번째 형식화 유형을 달성하는 방법이 있습니까? (또는 선택적으로 IntelliJ IDEA와 같은 다른 IDE에서.)



편집 : 내가 얻을 수있는 가장 가까운 것은 IntelliJ IDEA 13 Community 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);    

또한 다음과 같이 연결된 메서드 호출을 "정렬"할 수 있습니다.

    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는 람다의 여는 중괄호를 새 줄에 넣는 방법을 제공하지 않는 것 같지만 그렇지 않으면 상당히 합리적인 형식 지정 방법이므로 수락 된 것으로 표시합니다.


즉시 사용 가능한 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는이 중 일부를 수행하도록 구성 할 수도 있습니다. "settings"-> "code style"-> "java"아래의 "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());

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 (Mars)에는 람다 식 포맷터 옵션이 있습니다.

이동 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

함수 뒤에 빈 주석 "//"을 추가하여 한 줄 문을 형식화합니다.

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

이 질문은 이제 오래되었고 안타깝게도 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스크린 샷에서와 같이 템플릿을 선택하고 "Enter"를 클릭합니다. 끝난!

템플릿 적용 후 결과


이상적은 아니지만 약간 조밀 한 섹션에 대해서만 포맷터를 끌 수 있습니다. 예를 들면

  //@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> 코드 스타일> 포맷터"로 이동하십시오. "Edit ..."버튼을 클릭하고 "Off / On Tags"탭으로 이동하여 태그를 활성화합니다.

참고 URL : https://stackoverflow.com/questions/24649971/java-8-formatting-lambda-with-newlines-and-indentation

반응형