Многострочная строка Java - PullRequest
467 голосов
/ 18 мая 2009

Исходя из Perl, я уверен, что мне не хватает средства "здесь-документ" для создания многострочной строки в исходном коде:

$string = <<"EOF"  # create a three-line string
text
text
text
EOF

В Java мне нужно иметь громоздкие кавычки и знаки плюс в каждой строке, когда я объединяю свою многострочную строку с нуля.

Какие есть лучшие альтернативы? Определить мою строку в файле свойств?

Редактировать : в двух ответах говорится, что StringBuilder.append () предпочтительнее плюсовой нотации. Может ли кто-нибудь уточнить, почему они так думают? Это не выглядит более предпочтительным для меня вообще. Я ищу способ обойти тот факт, что многострочные строки не являются языковой конструкцией первого класса, а это означает, что я определенно не хочу заменять языковую конструкцию первого класса (конкатенация строк с плюсом) вызовами методов. *

Редактировать : Чтобы прояснить мой вопрос, я совсем не беспокоюсь о производительности. Я обеспокоен ремонтопригодностью и проблемами проектирования.

Ответы [ 39 ]

444 голосов
/ 18 мая 2009

Звучит так, будто вы хотите создать многострочный литерал, которого нет в Java.

Ваша лучшая альтернатива - строки, которые просто + вместе. Некоторые другие опции, о которых упоминали люди (StringBuilder, String.format, String.join), будут предпочтительнее, только если вы начинаете с массива строк.

Учтите это:

String s = "It was the best of times, it was the worst of times,\n"
         + "it was the age of wisdom, it was the age of foolishness,\n"
         + "it was the epoch of belief, it was the epoch of incredulity,\n"
         + "it was the season of Light, it was the season of Darkness,\n"
         + "it was the spring of hope, it was the winter of despair,\n"
         + "we had everything before us, we had nothing before us";

по сравнению StringBuilder:

String s = new StringBuilder()
           .append("It was the best of times, it was the worst of times,\n")
           .append("it was the age of wisdom, it was the age of foolishness,\n")
           .append("it was the epoch of belief, it was the epoch of incredulity,\n")
           .append("it was the season of Light, it was the season of Darkness,\n")
           .append("it was the spring of hope, it was the winter of despair,\n")
           .append("we had everything before us, we had nothing before us")
           .toString();

по сравнению String.format():

String s = String.format("%s\n%s\n%s\n%s\n%s\n%s"
         , "It was the best of times, it was the worst of times,"
         , "it was the age of wisdom, it was the age of foolishness,"
         , "it was the epoch of belief, it was the epoch of incredulity,"
         , "it was the season of Light, it was the season of Darkness,"
         , "it was the spring of hope, it was the winter of despair,"
         , "we had everything before us, we had nothing before us"
);

по сравнению с Java8 String.join():

String s = String.join("\n"
         , "It was the best of times, it was the worst of times,"
         , "it was the age of wisdom, it was the age of foolishness,"
         , "it was the epoch of belief, it was the epoch of incredulity,"
         , "it was the season of Light, it was the season of Darkness,"
         , "it was the spring of hope, it was the winter of despair,"
         , "we had everything before us, we had nothing before us"
);

Если вы хотите новую строку для вашей конкретной системы, вам нужно либо использовать System.getProperty("line.separator"), либо вы можете использовать %n в String.format.

Другой вариант - поместить ресурс в текстовый файл и просто прочитать содержимое этого файла. Это было бы предпочтительным для очень больших строк, чтобы избежать ненужного раздувания ваших файлов классов.

186 голосов
/ 10 октября 2011

В Eclipse, если вы включите опцию «Удалить текст при вставке в строковый литерал» (в «Предпочтения»> «Java»> «Редактор»> «Ввод») и вставите многострочную строку в кавычки, она автоматически добавит " и \n" + для всех ваших линий.

String str = "paste your text here";
112 голосов
/ 18 мая 2009

Стивен Коулборн создал предложение для добавления многострочных строк в Java 7.

Также в Groovy уже есть поддержка многострочных строк .

94 голосов
/ 01 августа 2012

Это старая тема, но новое довольно элегантное решение (с 4 или 3 небольшими недостатками) заключается в использовании пользовательской аннотации.

Проверка: http://www.adrianwalker.org/2011/12/java-multiline-string.html

Проект, вдохновленный этой работой, размещен на GitHub:

https://github.com/benelog/multiline

Пример кода Java:

import org.adrianwalker.multilinestring.Multiline;
...
public final class MultilineStringUsage {

  /**
  <html>
    <head/>
    <body>
      <p>
        Hello<br/>
        Multiline<br/>
        World<br/>
      </p>
    </body>
  </html>
  */
  @Multiline
  private static String html;

  public static void main(final String[] args) {
    System.out.println(html);
  }
}

Недостатки

  1. что вы должны активировать соответствующую (предоставленную) аннотацию процессор.
  2. что строковая переменная не может быть определена как локальная переменная Проверка Проект Raw String Literals , где вы можете определить переменные как локальные переменные
  3. , что String не может содержать другие переменные, как в Visual Basic .Net с литералом XML (<%= variable %>): -)
  4. , что строковый литерал ограничен комментарием JavaDoc (/ **)

И вам, вероятно, придется настроить Eclipse / Intellij-Idea, чтобы не переформатировать автоматически ваши комментарии Javadoc.

Это может показаться странным (комментарии Javadoc не предназначены для встраивания чего-либо, кроме комментариев), но поскольку отсутствие многострочной строки в Java действительно раздражает в конце, я считаю, что это наименее худшее решение.

58 голосов
/ 18 мая 2009

Другим вариантом может быть сохранение длинных строк во внешнем файле и чтение файла в строку.

54 голосов
/ 03 ноября 2009

Это то, что вы должны никогда использовать, не задумываясь о том, что он делает. Но для одноразовых сценариев я использовал это с большим успехом:

Пример:

    System.out.println(S(/*
This is a CRAZY " ' ' " multiline string with all sorts of strange 
   characters!
*/));

Код:

// From: http://blog.efftinge.de/2008/10/multi-line-string-literals-in-java.html
// Takes a comment (/**/) and turns everything inside the comment to a string that is returned from S()
public static String S() {
    StackTraceElement element = new RuntimeException().getStackTrace()[1];
    String name = element.getClassName().replace('.', '/') + ".java";
    StringBuilder sb = new StringBuilder();
    String line = null;
    InputStream in = classLoader.getResourceAsStream(name);
    String s = convertStreamToString(in, element.getLineNumber());
    return s.substring(s.indexOf("/*")+2, s.indexOf("*/"));
}

// From http://www.kodejava.org/examples/266.html
private static String convertStreamToString(InputStream is, int lineNum) {
    /*
     * To convert the InputStream to String we use the BufferedReader.readLine()
     * method. We iterate until the BufferedReader return null which means
     * there's no more data to read. Each line will appended to a StringBuilder
     * and returned as String.
     */
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();

    String line = null; int i = 1;
    try {
        while ((line = reader.readLine()) != null) {
            if (i++ >= lineNum) {
                sb.append(line + "\n");
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return sb.toString();
}
44 голосов
/ 17 июля 2014

String.join

Java 8 добавил новый статический метод к java.lang.String, который предлагает немного лучшую альтернативу:

String.join( CharSequence delimiter , CharSequence... elements )

Используя его:

String s = String.join(
    System.getProperty("line.separator"),
    "First line.",
    "Second line.",
    "The rest.",
    "And the last!"
);
19 голосов
/ 18 мая 2009

Если вы определите свои строки в файле свойств, это будет выглядеть намного хуже. IIRC, это будет выглядеть так:

string:text\u000atext\u000atext\u000a

Обычно разумно не вставлять большие строки в источник. Возможно, вы захотите загрузить их как ресурсы, возможно, в формате XML или в читаемом текстовом формате. Текстовые файлы могут быть прочитаны во время выполнения или скомпилированы в исходный код Java. Если вы в конечном итоге разместите их в источнике, я предлагаю поставить + спереди и пропустить ненужные новые строки:

final String text = ""
    +"text "
    +"text "
    +"text"
;

Если у вас есть новые строки, вы можете захотеть использовать метод объединения или форматирования:

final String text = join("\r\n"
    ,"text"
    ,"text"
    ,"text"
);
17 голосов
/ 19 мая 2009

Плюсы преобразуются в StringBuilder.append, за исключением случаев, когда обе строки являются константами, поэтому компилятор может объединять их во время компиляции. По крайней мере, так обстоит дело с компилятором Sun, и я подозреваю, что большинство, если не все другие компиляторы будут делать то же самое.

Итак:

String a="Hello";
String b="Goodbye";
String c=a+b;

обычно генерирует точно такой же код, как:

String a="Hello";
String b="Goodbye":
StringBuilder temp=new StringBuilder();
temp.append(a).append(b);
String c=temp.toString();

С другой стороны:

String c="Hello"+"Goodbye";

совпадает с:

String c="HelloGoodbye";

То есть, нет смысла разбивать строковые литералы на несколько строк со знаком плюс для удобства чтения.

13 голосов
/ 08 октября 2016

В IntelliJ IDE вам просто нужно набрать:

""

Затем поместите курсор в кавычки и вставьте строку. Среда IDE развернет ее на несколько объединенных строк.

...