2016-08-10 2 views
0

В настоящее время я делаю кусок кода, который должен иметь возможность сопоставления некоторого регулярного выражения и выполнять некоторую замену внутри строки, которая соответствует регулярному выражению.Sonar жалуется: используйте StringBuilder вместо StringBuffer

Для этого я использую объект matcher в java. Но , как вы можете видеть по всему Интернету, все примеры используют StringBuffer, чтобы выполнить некоторую замену, используя метод appendreplacement и appendtail (oracleDoc).

Но когда я нажимаю свой код, Sonar жалуется на использование stringbuffer вместо stringbuilder.

  • Это предупреждение от Sonar является ошибкой в ​​этом случае?
  • Есть ли какая-либо библиотека, которая делает то же самое с использованием stringbuilder?

По-видимому, некоторые разработчики жалуются на то, что here.

Я нахожу способ не использовать StringBuffer и использовать StringBuilder, но я уверен, что это не так эффективно, как использование StringBuffer (и может быть плохой практикой). Вы можете скопировать пасту внутри теста JUnit этот пример кода ниже:

String entry = "Actual 4.11-6 and 13-5"; 
    String expectedReturn = "Actual 4*11^(-6) and 13^(-5)"; 

    String number = "(^|\\s)-?\\d+((\\.||,)\\d+){0,1}(.\\d+){0,1}-\\d+"; 
    Pattern pattern = Pattern.compile(number); 
    Matcher matcher = pattern.matcher(entry); 

    //USING STRING BUFFER 
    StringBuffer stringBuffer = new StringBuffer(); 
    String substring; 
    while(matcher.find()){ 
     substring = matcher.group(0); 
     matcher.appendReplacement(stringBuffer,substring.replace(".","*").replace("-","^(-")+")"); 
    } 
    matcher.appendTail(stringBuffer); 

    //USING STRING BUILDER 
    matcher = pattern.matcher(entry); 
    int lastIndex = 0; 
    StringBuilder stringBuilder = new StringBuilder(); 
    while(matcher.find()){ 
     stringBuilder.append(entry.substring(lastIndex,matcher.start())); 
     substring = matcher.group(0); 
     stringBuilder.append(substring.replace(".","*").replace("-","^(-")+")"); 
     lastIndex = matcher.end(); 
    } 
    stringBuilder.append(entry.substring(lastIndex,entry.length())); 

    Assert.assertEquals(expectedReturn,stringBuffer.toString()); 
    Assert.assertEquals(expectedReturn,stringBuilder.toString()); 

Информация: согласовани которые управляют StringBuilder для Append будет в JDK 9 source code и code review

ответ

4

Это предупреждение, а не ошибка. Sonar делает свою работу, предупреждая вас, что StringBuilder является предпочтительным because it is faster. Если API заставляет вас использовать StringBuffer, я бы использовал его и отключил предупреждения.

Я думаю реальную основную проблему с Pattern и оба буферами, что StringBuffer и StringBuilder не разделяют конкретный интерфейс для построения строк (Appendable более универсальный интерфейс, я думаю, что они должны разделять более конкретный интерфейс для построения строк, что-то вроде StringConstructor), что позволит вам переключать реализацию с нулевым усилием (обычно).

+0

«StringBuffer и StringBuilder не имеют определенного интерфейса». Они делают: они оба реализуют «Appendable». Или я просто не понимаю, что вы имеете в виду, и в этом случае вы могли бы прояснить? –

+0

@ OlivierGrégoire Да, извините, вы правы, это непонятно. «Appendable» - более общий интерфейс. Я думаю, что они должны использовать более конкретный интерфейс для построения строк, например, StringConstructor. – m0skit0

+0

Ну, технически они тоже (в OpenJDK). Оба расширяют 'AbstractStringBuilder', который, к сожалению, не является общедоступным. –