Java-эквиваленты С# String.Format() и String.Join()

Я знаю, что это немного вопрос новичков, но есть ли эквиваленты для строковых операций на С# в Java?

В частности, речь идет о String.Format и String.Join.

Ответ 1

Объект String Java имеет метод format (начиная с 1.5), но не метод join.

Чтобы получить кучу полезных методов String, которые уже не были включены, вы можете использовать org.apache.commons.lang.StringUtils.

Ответ 2

String.format. Что касается объединения, вам нужно написать свой собственный:

 static String join(Collection<?> s, String delimiter) {
     StringBuilder builder = new StringBuilder();
     Iterator<?> iter = s.iterator();
     while (iter.hasNext()) {
         builder.append(iter.next());
         if (!iter.hasNext()) {
           break;                  
         }
         builder.append(delimiter);
     }
     return builder.toString();
 }

Вышеизложенное http://snippets.dzone.com/posts/show/91

Ответ 3

Guava поставляется с классом Joiner.

import com.google.common.base.Joiner;

Joiner.on(separator).join(data);

Ответ 4

Начиная с Java 8, join() теперь доступен в виде двух методов класса в классе String. В обоих случаях первым аргументом является разделитель.

Вы можете передать индивидуальные CharSequence в качестве дополнительных аргументов:

String joined = String.join(", ", "Antimony", "Arsenic", "Aluminum", "Selenium");
// "Antimony, Arsenic, Alumninum, Selenium"

Или вы можете передать Iterable<? extends CharSequence>:

List<String> strings = new LinkedList<String>();
strings.add("EX");
strings.add("TER");
strings.add("MIN");
strings.add("ATE");

String joined = String.join("-", strings);
// "EX-TER-MIN-ATE"

Java 8 также добавляет новый класс StringJoiner, который вы можете использовать следующим образом:

StringJoiner joiner = new StringJoiner("&");
joiner.add("x=9");
joiner.add("y=5667.7");
joiner.add("z=-33.0");

String joined = joiner.toString();
// "x=9&y=5667.7&z=-33.0"

Ответ 6

Вы также можете использовать переменные аргументы для строк следующим образом:

  String join (String delim, String ... data) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < data.length; i++) {
      sb.append(data[i]);
      if (i >= data.length-1) {break;}
      sb.append(delim);
    }
    return sb.toString();
  }

Ответ 7

Что касается объединения, я считаю, что это может выглядеть немного менее сложно:

public String join (Collection<String> c) {
    StringBuilder sb=new StringBuilder();
    for(String s: c)
        sb.append(s);
    return sb.toString();
}

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

edit Добавление: добавление String может быть медленным, но если вы работаете с графическим интерфейсом или какой-то кратковременной процедурой, то действительно не имеет значения, возьмете ли вы 0,500 секунд или 0,006, так что если бы у вас была коллекция, называемая "joinMe", который вы хотите добавить к существующей строке "target", было бы ужасно просто вставить это:

for(String s : joinMe)
    target += s;

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

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

Ответ 8

Вот довольно простой ответ. Используйте +=, поскольку это меньше кода и пусть оптимизатор преобразует его в StringBuilder для вас. Используя этот метод, вам не нужно делать никаких "последних" проверок в вашем цикле (повышение производительности), и вам не нужно беспокоиться о том, чтобы удалить все разделители в конце.

        Iterator<String> iter = args.iterator();
        output += iter.hasNext() ? iter.next() : "";
        while (iter.hasNext()) {
            output += "," + iter.next();
        }

Ответ 9

Я не хотел импортировать всю библиотеку Apache, чтобы добавить простую функцию соединения, поэтому вот мой взлом.

    public String join(String delim, List<String> destinations) {
        StringBuilder sb = new StringBuilder();
        int delimLength = delim.length();

        for (String s: destinations) {
            sb.append(s);
            sb.append(delim);
        }

        // we have appended the delimiter to the end 
        // in the previous for-loop. Let now remove it.
        if (sb.length() >= delimLength) {
            return sb.substring(0, sb.length() - delimLength);
        } else {
            return sb.toString();
        }
    }

Ответ 10

Если вы хотите объединить (объединить) несколько строк в один, вы должны использовать StringBuilder. Это намного лучше, чем использование

for(String s : joinMe)
    target += s;

Существует также небольшая победа над StringBuffer, поскольку StringBuilder не использует синхронизацию.

Для универсального метода полезности, подобного этому, он будет (в конце концов) вызываться много раз во многих ситуациях, поэтому вы должны сделать его эффективным и не выделять много преходящих объектов. Мы профилировали множество различных приложений Java и почти всегда находим, что конкатенация строк и распределение строк / char [] занимают значительное количество времени/памяти.

Наш метод многократной записи → string сначала вычисляет размер требуемого результата, а затем создает StringBuilder с этим начальным размером; это позволяет избежать ненужного дублирования/копирования внутреннего char [], используемого при добавлении строк.

Ответ 11

Я написал собственный:

public static String join(Collection<String> col, String delim) {
    StringBuilder sb = new StringBuilder();
    Iterator<String> iter = col.iterator();
    if (iter.hasNext())
        sb.append(iter.next().toString());
    while (iter.hasNext()) {
        sb.append(delim);
        sb.append(iter.next().toString());
    }
    return sb.toString();
}

но Collection не поддерживается JSP, поэтому для функции tag я написал:

public static String join(List<?> list, String delim) {
    int len = list.size();
    if (len == 0)
        return "";
    StringBuilder sb = new StringBuilder(list.get(0).toString());
    for (int i = 1; i < len; i++) {
        sb.append(delim);
        sb.append(list.get(i).toString());
    }
    return sb.toString();
}

и поместите в файл .tld:

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
    <function>
        <name>join</name>
        <function-class>com.core.util.ReportUtil</function-class>
        <function-signature>java.lang.String join(java.util.List, java.lang.String)</function-signature>
    </function>
</taglib>

и использовать его в файлах JSP как:

<%@taglib prefix="funnyFmt" uri="tag:com.core.util,2013:funnyFmt"%>
${funnyFmt:join(books, ", ")}

Ответ 12

StringUtils - довольно полезный класс в библиотеке Apache Commons Lang.

Ответ 13

Существует MessageFormat.format(), который работает как С# String.Format().

Ответ 14

Я вижу много чрезмерно сложных реализаций String.Join здесь. Если у вас нет Java 1.8, и вы не хотите импортировать новую библиотеку, то реализация ниже должна быть достаточной.

public String join(Collection<String> col, String delim) {
    StringBuilder sb = new StringBuilder();
    for ( String s : col ) {
        if ( sb.length() != 0 ) sb.append(delim);
        sb.append(s);
    }
    return sb.toString();
}

Ответ 15

ArrayList<Double> j=new ArrayList<>; 
j.add(1);
j.add(.92);
j.add(3); 
String ntop=j.toString(); //ntop= "[1, 0.92, 3]" 

Таким образом, String ntop сохраняет значение всей коллекции с помощью разделителей и скобок запятой.

Ответ 16

Я бы просто использовал оператор конкатенации строк "+" для объединения двух строк. s1 += s2;