Использование Строки или StringBuffer в Java: который лучше?

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

Так, в различных методах Java, которые должны использоваться?

Например, в PreparedStatement, должен запросить быть StringBuffer:

    String query = ("SELECT * " +
                    "FROM User " +
                    "WHERE userName = ?;");

    try {
        ps = connection.prepareStatement(query);

И с другой стороны, в Строке служебные методы как:

public static String prefixApostrophesWithBackslash(String stringIn) {
    String stringOut = stringIn.replaceAll("'", "\\\\'");
    return stringOut;
}

И:

 // Removes a char from a String.
public static String removeChar(String stringIn, char c) {
    String stringOut = ("");
    for (int i = 0; i < stringIn.length(); i++) {
        if (stringIn.charAt(i) != c) {
            stringOut += stringIn.charAt(i);
        }
    }
    return stringOut;
}

Я должен использовать StringBuffers? Особенно, где repalceAll не доступен для таких объектов так или иначе.

Спасибо

Г-н Morgan.

Спасибо за весь совет. StringBuffers были заменены StringBuilders и Строками, замененными StringBuilders, где я думал это лучше всего.

5
задан Mr Morgan 19 July 2010 в 08:49
поделиться

6 ответов

Вам почти никогда не понадобится использовать StringBuffer.

Вместо StringBuffer вы, вероятно, имеете в виду StringBuilder. StringBuffer похож на StringBuilder, за исключением того, что он также обеспечивает безопасность потоков. Эта безопасность потоков редко нужна на практике и просто заставит ваш код работать медленнее.

Ваш вопрос, похоже, не о String vs StringBuffer, а об использовании встроенных методов или реализации кода самостоятельно. Если есть встроенный метод, который делает именно то, что вам нужно, то, вероятно, вам следует использовать его. Есть вероятность, что он оптимизирован гораздо лучше, чем код, который вы бы написали.

7
ответ дан 18 December 2019 в 14:41
поделиться

Нет простого ответа (кроме повторения мантры StringBuilder против StringBuffer ...). Вы действительно хорошо разбираетесь в том, что происходит «под капотом», чтобы выбрать наиболее эффективное решение.

В вашем первом примере String - это правильный путь. Компилятор Java может генерировать практически оптимальный код (используя StringBuilder , если необходимо) для любого выражения, состоящего из последовательности конкатенаций строк. И, если все конкатенационные строки являются константами или литералами, компилятор может фактически выполнить конкатенацию во время компиляции.

Во втором примере не совсем ясно, что лучше: String или StringBuilder ... или они будут примерно эквивалентны. Чтобы понять это, нужно взглянуть на код класса java.util.regex.Matcher .

РЕДАКТИРОВАТЬ - Я посмотрел на код, и на самом деле не имеет большого значения, используете ли вы String или StringBuilder в качестве источника. Внутренне метод Matcher.replaceAll создает новый StringBuilder и заполняет его, добавляя фрагменты из исходной String и замещающей String.

В третьем примере явно лучше всего использовать StringBuilder . Компилятор Java текущего поколения не может оптимизировать код (как написано), чтобы избежать создания новой строки при добавлении каждого символа.

3
ответ дан 18 December 2019 в 14:41
поделиться

Для следующего сегмента кода

 // Removes a char from a String.
public static String removeChar(String stringIn, char c) {
    String stringOut = ("");
    for (int i = 0; i < stringIn.length(); i++) {
        if (stringIn.charAt(i) != c) {
            stringOut += stringIn.charAt(i);
        }
    }
    return stringOut;
}

Вы можете просто сделать stringIn.replaceAll (c + "", "")

1
ответ дан 18 December 2019 в 14:41
поделиться

Даже в коде MT, необычно иметь несколько потоков, добавляющих данные в строку. StringBuilder почти всегда предпочтительнее StringBuffer.

1
ответ дан 18 December 2019 в 14:41
поделиться

Для случаев, которые можно считать одиночными многопоточным, лучше всего будет StringBuilder . Он не добавляет никаких накладных расходов на синхронизацию, в отличие от StringBuffer.

Объединение строк оператором '+' "хорошо" только в том случае, если вам лень использовать StringBuilder или вы просто хотите, чтобы код был легко читаемым, и это приемлемо с точки зрения производительности, как в сообщении журнала запуска "LOG. info ("Начальный экземпляр" + inst_id + "of" + app_name); "

0
ответ дан 18 December 2019 в 14:41
поделиться

Современные компиляторы уже оптимизируют код. Поэтому некоторые строковые дополнения будут оптимизированы для использования StringBuilder, и мы можем оставить строковые дополнения, если считаем, что это повышает читабельность.

Пример 1:

String query = ("SELECT * " +
                "FROM User " +
                "WHERE userName = ?;");

будет оптимизирован до чего-то вроде:

StringBuiler sb = new StringBuilder();
sb.append("SELECT * ");
sb.append("FROM User ");
sb.append("WHERE userName = ?;");
String query = sb.toString();

Пример 2:

String numbers = "";
for (int i = 0;i < 20; i++)
  numbers = numbers + i;

Это не может быть оптимизировано, и мы должны использовать StringBuilder в коде.


Я сделал это наблюдение для SUN jdk1.5+. Так что для более старых версий Java или других jdk все может быть иначе. Там может быть спасением всегда кодировать StringBuilder (или StringBuffer для jdk 1.4.2 и старше).

1
ответ дан 18 December 2019 в 14:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: