font - oracle java jlabel




Многострочная строка Java (20)

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

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

Исходя из Perl, я уверен, что отсутствует способ «here-document» для создания многострочной строки в исходном коде:

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

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

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

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

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


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!"
);

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

String str = "paste your text here";

В IntelliJ IDE вам просто нужно ввести:

""

Затем поместите курсор внутри кавычек и вставьте строку. IDE расширит его на несколько конкатенированных строк.


Вы можете объединить свои добавления в отдельный метод, например:

public static String multilineString(String... lines){
   StringBuilder sb = new StringBuilder();
   for(String s : lines){
     sb.append(s);
     sb.append ('\n');
   }
   return sb.toStirng();
}

В любом случае, предпочитайте StringBuilder для плюсовой нотации.


Достаточно эффективное и независимое от платформы решение будет использовать системное свойство для разделителей строк и класс StringBuilder для построения строк:

String separator = System.getProperty("line.separator");
String[] lines = {"Line 1", "Line 2" /*, ... */};

StringBuilder builder = new StringBuilder(lines[0]);
for (int i = 1; i < lines.length(); i++) {
    builder.append(separator).append(lines[i]);
}
String multiLine = builder.toString();

Если вам нравится гуава google так же, как и я, она может дать довольно чистое представление и хороший, простой способ не жестко кодировать символы новой строки:

String out = Joiner.on(newline).join(ImmutableList.of(
    "line1",
    "line2",
    "line3"));

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

string:text\u000atext\u000atext\u000a

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

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

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

final String text = join("\r\n"
    ,"text"
    ,"text"
    ,"text"
);

Когда используется длинная серия +, создается только один StringBuilder, если только String не определяется во время компиляции, и в этом случае не используется StringBuilder!

Единственный момент, когда StringBuilder более эффективен, - это использование нескольких операторов для построения String.

String a = "a\n";
String b = "b\n";
String c = "c\n";
String d = "d\n";

String abcd = a + b + c + d;
System.out.println(abcd);

String abcd2 = "a\n" +
        "b\n" +
        "c\n" +
        "d\n";
System.out.println(abcd2);

Примечание. Создается только один StringBuilder.

  Code:
   0:   ldc     #2; //String a\n
   2:   astore_1
   3:   ldc     #3; //String b\n
   5:   astore_2
   6:   ldc     #4; //String c\n
   8:   astore_3
   9:   ldc     #5; //String d\n
   11:  astore  4
   13:  new     #6; //class java/lang/StringBuilder
   16:  dup
   17:  invokespecial   #7; //Method java/lang/StringBuilder."<init>":()V
   20:  aload_1
   21:  invokevirtual   #8; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   24:  aload_2
   25:  invokevirtual   #8; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   28:  aload_3
   29:  invokevirtual   #8; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   32:  aload   4
   34:  invokevirtual   #8; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   37:  invokevirtual   #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   40:  astore  5
   42:  getstatic       #10; //Field java/lang/System.out:Ljava/io/PrintStream;
   45:  aload   5
   47:  invokevirtual   #11; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   50:  ldc     #12; //String a\nb\nc\nd\n
   52:  astore  6
   54:  getstatic       #10; //Field java/lang/System.out:Ljava/io/PrintStream;
   57:  aload   6
   59:  invokevirtual   #11; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   62:  return

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

Сделайте это как можно яснее и проще.


На самом деле, это самая чистая реализация, которую я видел до сих пор. Он использует аннотацию для преобразования комментария в строковую переменную ...

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

Итак, конечный результат заключается в том, что переменная html содержит многострочную строку. Нет кавычек, нет плюсов, нет запятых, просто чистая строка.

Это решение доступно по следующему URL-адресу: http://www.adrianwalker.org/2011/12/java-multiline-string.html

Надеюсь, это поможет!


Один хороший вариант.

import static some.Util.*;

    public class Java {

        public static void main(String[] args) {

            String sql = $(
              "Select * from java",
              "join some on ",
              "group by"        
            );

            System.out.println(sql);
        }

    }


    public class Util {

        public static String $(String ...sql){
            return String.join(System.getProperty("line.separator"),sql);
        }

    }

Плюсы преобразуются в 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";

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


Похоже, вы хотите сделать многострочный литерал, которого нет в Java.

Ваша лучшая альтернатива - это строки, которые просто + 'd вместе. Некоторые другие варианты, упомянутые выше (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";

Versus 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();

Versus 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"
);

Versus 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") для вашей конкретной системы, вам нужно либо использовать System.getProperty("line.separator") , либо вы можете использовать %n в String.format .

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


См. Java Stringfier . При необходимости превращает ваш текст в escape-блок Java StringBuilder.


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

import sys
import string
import os

print 'new String('
for line in sys.stdin:
    one = string.replace(line, '"', '\\"').rstrip(os.linesep)
    print '  + "' + one + ' "'
print ')'

Поместите это в файл с именем javastringify.py и свою строку в файл mystring.txt и запустите его следующим образом:

cat mystring.txt | python javastringify.py

Затем вы можете скопировать вывод и вставить его в свой редактор.

Измените это по мере необходимости для обработки любых особых случаев, но это работает для моих нужд. Надеюсь это поможет!


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

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

Изменить: Вышеприведенный URL-адрес кажется сломанным. Проект, вдохновленный этой работой, размещен на GitHub:

https://github.com/benelog/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);
  }
}

Недостатком является то, что вы должны активировать соответствующий (предоставленный) обработчик аннотации.

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

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


openjdk.java.net/jeps/326 реализует многострочные строки, поэтому вы сможете написать что-то вроде:

String s = `
    text
    text
    text
  `;

Он запланирован как предварительный просмотр функции в JDK 12 .



Я предлагаю использовать утилиту, как предложено ThomasP, а затем связать это с вашим процессом сборки. Внешний файл все еще присутствует, чтобы содержать текст, но файл не читается во время выполнения. Рабочий процесс следующий:

  1. Создайте утилиту «текстовый файл в java-код» и установите флажок в управлении версиями
  2. На каждой сборке запустите утилиту с файлом ресурса, чтобы создать обновленный источник java
  3. Источник Java содержит заголовок, class TextBlock {...за которым следует статическая строка, которая автоматически генерируется из файла ресурсов
  4. Создайте сгенерированный Java-файл с остальной частью вашего кода.

    import org.apache.commons.lang3.StringUtils;

    String multiline = StringUtils.join(new String[] {
        "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"
    }, "\n");




multiline