Когда вы должны явно использовать StringBuilder?

Как я понимаю, когда я делаю String baz = "foo" + "bar" + "123" компилятор Java внутренне заменяет выражение StringBuilder, Однако наш учитель Java сказал нам, что это хорошая практика, всегда использовать StringBuilder явно...

Правильно ли я полагаю, что мне нужно будет только явно использовать StringBuilder при конкатенации внутри циклов, как указано в ответе на вопрос переполнения стека Строитель строк против конкатенации строк? Существуют ли другие случаи, когда вы должны явно использовать StringBuilder вместо + или же +=?

3 ответа

Решение

Он более общий, чем "внутренние циклы" - в любое время вы хотите объединить несколько операторов, и вам не нужен промежуточный результат в виде строки. Например:

StringBuilder builder = new StringBuilder("Start");
if (someCondition) {
    builder.append("Foo");
}
if (someOtherCondition) {
    builder.append("Bar");
}
builder.append("End");
String result = builder.toString();

Хотя вы могли бы написать это как:

String result = "Start" + (someCondition ? "Foo" : "")
    + (someOtherCondition ? "Bar" : "") + "End";

... это становится трудно читать. И если есть еще заявления в if тела, это может даже не быть осуществимым.

Чтобы исправить что-то в вашем вопросе, хотя:

Насколько я понимаю, когда я делаю String baz = "foo" + "bar" + "123", компилятор Java внутренне заменяет выражение на StringBuilder.

Нет, когда вы пишете это выражение, компилятор распознает, что это константа времени компиляции, и заменяет ее на

String baz = "foobar123";

Это очень веская причина, чтобы не использовать явно StringBuilder - приведенный выше код явно более эффективен во время выполнения, чем

String baz = new StringBuilder("foo").append("bar").append("123").toString();

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

Они также хороши для реализации таких вещей, как C# 'out' ключевое слово с помощью String. пример

public int getInt(StringBuilder error)
{
    int retVal = 0;

    if (someErrorOccured)
        error.append("Couldn't get int because of...");
    else
        retVal = whatItsSupposedToBe;

    return retVal;
}

Оби-Ван сказал, что только Ситх мыслит абсолютами или чем-то подобным...

Хорошо, что вы знаете, что компилятор Java внутренне заменяет "+" в строках с использованием StringBuilder, Это то, для чего нужны компиляторы: сделать жизнь проще.

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

Замена

return "User " + userName + " said";

с

new StringBuilder().append("User ").append(userName).append(" said").toString();

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

Однако, когда сложение применяется не только к строкам, но и к числам, вероятно, решение с StringBuilder иногда может быть более читабельным.

return "User" + a + b + " said: " + (c + d);

может быть более запутанным, как:

return new StringBuilder().append("User ").append(a).append(b)
  .append(" said: ").append(c+d).toString();  

Но это прежде всего вопрос мнения и стиля кодирования. "Должен" не очень хорошее слово здесь.

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