Я хотел бы добиться с помощью лямбда-отступа следующего:
Многострочный оператор:
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? (Или, необязательно, в другой среде IDE, например IntelliJ IDEA.)
РЕДАКТИРОВАТЬ: Самое близкое, что я мог получить, было с 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, похоже, не предоставляет способ поместить открывающую скобку лямбда в новую строку, в противном случае это довольно разумный способ форматирования, поэтому я отмечу его как принятый.
.filter(x -> x.contains("(M)"))
? Гораздо проще ... Если вы действительно говорите о местах, где вам нужно несколько операторов, было бы лучше привести пример, который в этом нуждался.Ctrl+Alt+F
если вы автоматически форматируете чужой код.x
без открытия фигурной скобки и ее закрытия, поэтому сначала я использовал оператор, а не простую версию.Ответы:
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());
источник
В 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
.источник
.filter(c -> c.getValue().equals(newValue))
операторы в лямбде , например , также будут заключены непосредственно перед .equals. Было бы хорошо, если бы такой параметр применялся только к лямбда-методу; Я вижу, что это может быть сложно реализовать ...Eclipse (Mars) имеет возможность форматирования лямбда-выражений.
Идти к
Window > Preferences > Java > Code Style > Formatter
Нажмите
Edit
кнопку, перейдите кBraces
тегу и установитеLambda Body
значениеNext Line Indented
Другой вариант - обновить эти свойства в настройках вашего проекта. (
yourWorkspace > yourProject > .settings > org.eclipse.jdt.core.prefs
)источник
Этот вопрос теперь устарел, и, к сожалению, конфигурация по умолчанию средства форматирования 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
шаблон как на скриншоте и нажмите «Enter». Готово!источник
Я форматирую однострочный оператор, добавляя пустой комментарий «//» после функций.
List<Integer> list = Arrays.stream(x) // .filter((n) -> n % 2 == 0) // .map((n) -> n * 4) // .boxed() // .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> Стиль кода> Форматирование». Нажмите кнопку «Изменить ...», перейдите на вкладку «Выкл. / Вкл. Теги» и включите теги.
источник
Опция, которая сработала для меня, заключалась в установке галочки
Never join already wrapped lines
в разделе «Перенос строк» в программе форматирования в настройках.источник
Если у вас еще нет настраиваемого модуля форматирования Eclipse:
Настройки Eclipse Java> Стиль кода> Форматирование Создать Введите имя Нажмите ОК Разрывы строк управления
Отредактируйте вкладку профиля «Перенос линии». Установите флажок «Никогда не объединять уже перенесенные линии»
Это закончится так
String phrase = employeeList .stream() .filter(p -> p.getAge() >= 33) .map(p -> p.getFirstName()) .collect(Collectors.joining(" and ", "In Germany ", " are of legal age."));
Нужно вводить каждый. начать со следующей строки
кредиты - https://www.selikoff.net/2017/07/02/eclipse-and-line-wrapping/
источник
Последняя версия Eclipse имеет встроенный форматировщик java 8, goto
Preferences -> Java -> Code Style -> Formatter -> Active profile and Select Eclipse 2.1[built-in] profile
источник