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

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

Конкретно я говорю о String.Format и String.Join.

Итак, есть String.format, но мне придется откатить собственное соединение.

Omar Kooheji 09.10.2008 19:14

Для join () мне нравится этот ответ: stackoverflow.com/a/6116469/562139

scorpiodawg 08.03.2012 23:38
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
111
2
75 501
16
Перейти к ответу Данный вопрос помечен как решенный

Ответы 16

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

Точнее: StringBuffer для jdk1.4 и ниже, StringBuilder для jdk1.5 и более поздних версий, поскольку последний не синхронизируется, следовательно, немного быстрее.

VonC 09.10.2008 19:39

Вместо двух вызовов iter.hasNext () я обычно добавляю разделитель, а затем «возвращаю buf.substring (0, buf.length () - delimited.length ())».

Vilmantas Baranauskas 09.10.2008 19:40

Вы можете немного упростить его, выйдя раньше, чтобы избежать разделителя: while (true) (add_iter; if (! Iter.hasNext ()) break; add_delim;}

13ren 21.03.2009 15:50
Ответ принят как подходящий

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

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

Коллекции google: google-collections.googlecode.com также имеет Joiner.

Ron 21.10.2009 17:20

К вашему сведению, к комментарию Рона, google-коллекции были переименованы в Guava некоторое время назад.

Kevin Bourrillion 02.09.2011 03:21

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

Duncan Jones 12.03.2015 18:42

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

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;

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

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

Цикл for правильный, но вы также должны сделать его Collection <String>. Если вы этого не сделаете, вам придется сказать «for (Object o: c)», потому что вы не можете гарантировать, что все в c было строкой.

Michael Myers 09.10.2008 21:00

Хорошая мысль, я еще более ржавый с Generics. Отредактирую в.

Bill K 09.10.2008 21:02

При объединении inline: string + string + string компилятор фактически использует StringBuilder для добавления значений. Интересно, если в методе for-loop у вас есть второй, сделает ли компилятор то же самое.

Spencer Kormos 09.10.2008 22:46

@Spencer K: он использует StringBuilder, но создает новый для каждой итерации (вряд ли самый эффективный метод, но тогда как компилятор должен знать?). Я не знаю, может ли JIT-компилятор оптимизировать это во время выполнения.

Michael Myers 09.10.2008 23:26

Код стиля «цикл и добавление» содержит ошибки, поскольку он излишне применяет произвольное ограничение на входной диапазон его аргументов (на основе общего использования памяти и реализации GC). Этого следует избегать любой ценой, так как никогда не знаешь, когда он тебя укусит.

soru 21.10.2009 17:22

@soru: не могли бы вы объяснить ошибку? Обычный способ создания большой строки из последовательности частей - «зациклить и добавить». Если вы утверждаете, что вам не следует создавать большие строки, а вместо этого использовать только онлайн-алгоритмы, то вы должны знать, что такие ограничения усложнят вашу программу.

Ian 27.04.2011 12:04

@lan Я думаю, он исходит из другого языка. Использование построителя строк не должно вызывать никаких проблем, и, если у вас не закончится память, не будет ошибок. Если вы использовали конкатенацию строк, у вас могут возникнуть проблемы с памятью, но вы, вероятно, ничего не заметите.

Bill K 28.04.2011 01:14

Попробуйте, напишите в обоих направлениях, посмотрите, какой из них позволяет использовать большее значение c.size () без падения.

soru 04.05.2011 21:51

@soru "Падение"? Если вы имеете в виду нехватку памяти, это не ошибка - просто в одном решении может закончиться нехватка памяти раньше. Я также не уверен, что вы предлагаете в качестве альтернативы. Если альтернатива, которую вы имеете в виду, - это другая библиотека - вы действительно думаете, что она не делает именно этого под листами?

Bill K 04.05.2011 22:34

Если код, написанный одним способом (цикл с + =), не работает, а код, написанный другим способом (явный StringBuilder) - нет, то код, написанный таким образом, имеет ошибку. FindBugs помечает это как таковое. Кажется, вы считаете ошибки, связанные с производительностью, не ошибками, хотя на самом деле они - единственное, что хуже ошибок, связанных с потоками. Не существует практического способа даже указать обстоятельства, при которых код неограниченного использования памяти завершится ошибкой.

soru 05.05.2011 21:43

Ой-подожди. Вы говорите + =? Да, это отстой. В настоящее время цикл и добавление в моем ответе используют StringBuilder, и это то, о чем я говорю. Хотя + = значительно улучшился, вы действительно не хотите использовать его внутри цикла - не столько потому, что он глючит, сколько потому, что он может работать как дерьмо (ошибка - это не термин, обычно используемый для проблем с производительностью - по крайней мере, не за мои 20 лет программирования). Также JIT может значительно улучшить это, но я бы не стал на это полагаться.

Bill K 06.05.2011 01:31

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

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

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

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

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

re: предварительный расчет размера: Когда это работает, это здорово. Это не всегда возможно. Я помню, как где-то читал, что удвоение размера буфера каждый раз (или действительно умножение на любой фиксированный коэффициент) дает что-то вроде производительности n log n, что на самом деле не так уж и плохо. В общем случае альтернативой является составление списка всех строк, которые вы планируете объединить. Если вы используете ArrayList, у вас снова есть копирование (если вы заранее не знаете длину своей последовательности), а если вы используете LinkedList, тогда он использует больше памяти и сборку мусора с объектами узлов. Иногда не получается победить. Попробуй!

Ian 27.04.2011 11:58

Приведенные выше примеры / запросы предполагали некоторую упорядоченную коллекцию или массив строк для объединения. Кроме того, предварительно вычисляя размер, вы избегаете лишних неиспользуемых символов, к которым обычно приводит рост внутреннего массива char [].

djb 07.06.2011 19:32

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

Возможно, вы не заметили, что принятый ответ, опубликованный 8 месяцев назад, уже содержит ту же информацию; stackoverflow.com/questions/187676/string-operations-in-java‌ /…

Jonik 25.06.2009 21:04

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

Потому что это плохая практика и медлительность.

MrSnowflake 01.07.2014 12:06

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

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

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

import com.google.common.base.Joiner;

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

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

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

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

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 хранит значение всей коллекции с разделителями-запятыми и скобками.

Я не уверен, на какую часть вопроса это отвечает? Это не String.format, если вы не планируете добавлять биты строки в массив побитно, а [1,0.92,3] не так универсален, как обычная строка .join.

Omar Kooheji 21.11.2013 17:26

Начиная с 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"

Я не хотел импортировать всю библиотеку 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();
        }
    }

@MrSnowflake Есть ли в стандартном построителе строк метод removeCharAt (int index). Он не отображается в версии, которую я использую

NSjonas 31.07.2014 20:43

@NSjonas - да, его редактирование моего ответа неверно. removeCharAt не существует, и вся функция больше не возвращает String ... Исправлю это.

Martin Konecny 31.07.2014 20:44

пока вы в нем ... это текущее решение вызовет «исключение индекса за пределами границ, если вы передадите пустой список»

NSjonas 01.08.2014 01:04

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

NSjonas 01.08.2014 01:35

Спасибо за отзыв. Обновлено.

Martin Konecny 01.08.2014 08:54

Приношу свои извинения, это не removeCharAt(int index), а deleteCharAt(int). Но у него такой же функционал.

MrSnowflake 03.08.2014 23:38

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

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

Очень элегантное решение, без сторонних библиотек!

Denis Itskovich 30.11.2014 20:58

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

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

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