Использование String или StringBuffer в Java: что лучше? - PullRequest
5 голосов
/ 19 июля 2010

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

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

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

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

    try {
        ps = connection.prepareStatement(query);

И снова, в String утилиты типа:

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 недоступно для таких объектов.

Спасибо

Мистер Морган.

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

Ответы [ 6 ]

7 голосов
/ 19 июля 2010

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

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

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

3 голосов
/ 19 июля 2010

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

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

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

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

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

1 голос
/ 19 июля 2010

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

Пример 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 или разных jdks он может быть разным.Там может быть сохранено всегда код StringBuilder (или StringBuffer для jdk 1.4.2 и старше).

1 голос
/ 19 июля 2010

Даже в МТ-коде необычно, когда несколько потоков добавляют материал к строке.StringBuilder почти всегда предпочитается StringBuffer.

1 голос
/ 19 июля 2010

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

 // 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+"","")

0 голосов
/ 19 июля 2010

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

Конкатенация строк оператором «+» «хороша», только если вам лень использовать StringBuilder или вы просто хотите, чтобы код легко читалсяприемлемо с точки зрения производительности, как в сообщении журнала запуска "LOG.info (" Starting instance "+ inst_id +" of "+ app_name);"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...