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

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

Конкретно я говорю о String.Format а также String.Join,

16 ответов

Решение

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

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

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

Гуава идет с Joiner класс

import com.google.common.base.Joiner;

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

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

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

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"

TextUtils.join доступен на Android

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

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

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

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

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

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), так что я могу быть немного ржавым, но я уверен, что концепция верна,

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

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

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

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

Я не хотел импортировать целую библиотеку 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's now remove it.
        if (sb.length() >= delimLength) {
            return sb.substring(0, sb.length() - delimLength);
        } else {
            return sb.toString();
        }
    }

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

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

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

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

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

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

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, поэтому для функции тега я написал:

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, ", ")}

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

Есть MessageFormat.format() который работает как C# String.Format(),

Я вижу много слишком сложных реализаций 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();
}
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 хранит значение всей коллекции с разделителями-запятыми и скобками.

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

Другие вопросы по тегам