2015-10-02 2 views
0
private String generateSuffix(List<String[]> searches, List<String[]> sorts) { 
     String ret = ""; 
     if (searches != null && !searches.isEmpty()) { 
      ret += "where "; 
      for (String[] search : searches) { 
       if (search.length < 3) { 
        continue; 
       } 
       ret += search[0] + search[1] + search[2] + " and "; 
      } 
      ret = ret.substring(0, ret.length() - 5); 
     } 

     ret += " order by "; 
     if (sorts != null && !sorts.isEmpty()) { 
      for (String[] sort : sorts) { 
       if (sort.length < 2) { 
        continue; 
       } 
       ret += sort[0] + " " + sort[1] + ","; 
      } 
     } 
     return ret; 
    } 
} 

Сканирование SONAR показало, что использование «+» для конкатенации строк в цикле является основной ошибкой. Это не дает большого понимания того, как эта ошибка может быть исправлена. Можно ли использовать StringBuilder в этом случае? Если да, то как мне пойти на реализацию StringBuilder с расширенным циклом? Я не очень хорошо знаком с использованием StringBuilder.using stringbuilder with for loop

Также можно добавить StringBuilder в список, как показано ниже? Мне нужно избавиться от кода «value + = ds;» и значение = d + ""»

private List<TransactionSearchField> checkSearches(List<TransactionSearchField> searchesIn) { 
    List<TransactionSearchField> searches = new ArrayList<TransactionSearchField>(); 
    if (searchesIn != null) { 
     for (TransactionSearchField search : searchesIn) { 
      String value = search.getValue(); 
      if (value != null && value.length() > 0) { 
       if (search.getDataType().equals(double.class)) { 
        String[] dSplit = value.split(","); 
        value = ""; 
        for (String ds : dSplit) { 
         value += ds; 
        } 
        double d; 
        try { 
         d = Double.parseDouble(value); 
         value = d + ""; 
        } catch (IllegalArgumentException e) { 
         value = ""; 
        } 
       } else if (search.getDataType().equals(Date.class)) { 
        value = formatDate(generateDate(value)); 
       } 
       searches.add(new TransactionSearchField(search.getDataType(), search.getTableField(), search.getLogic(), value, search.getViewField())); 
      } 
     } 
    } 
    return searches; 
} 
+1

StringBuilder SB = новый StringBuilder(); для (String s: yourStringArray) { sb.append (s); } Строковый результат = sb.toString(); Скопируйте и отформатируйте его –

+2

Если вы используете java8, используя ['StringJoiner'] (https://docs.oracle.com/javase/8/docs/api/java/util/StringJoiner.html), это может быть вариант. @Rainbolt: Не дубликат этого вопроса. OP только удаляет последние '' и ''. Также речь идет не о производительности. – fabian

+0

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

ответ

1

Вы можете попробовать что-то вроде этого:.

StringBuilder sb = new StringBuilder(); 
for(String[] sort : sorts){ 
    //Your other logic 
    sb.append(sort[0]); 
    sb.append(" "); 
    sb.append(sort[1]); 
    sb.append(","); 
} 
4

код как

result = result + newPart; 

по существу (при условии, результат String)

result = new StringBuilder(result).append(newPart).toString(); 

Если вы поместите его в цикл, в eac h итерации вы создадите объект new StringBuilder, который скопирует все символы из result String, затем добавит newPart к нему, а затем создаст другую строку, которая будет храниться в переменной result.

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

Чтобы избежать этой проблемы, вместо конкатенации как

String result = ""; 
for (String newPart : otherStrings){ 
    result = result + newPart; 
    result = result + ", "; 
} 

мы должны создать один StringBuilder и append новые части к идентификатору. Преимущество класса StringBuilder заключается в том, что он содержит символы в массиве символов, который довольно большой, поэтому он имеет свободное пространство для новых. Если этого пространства в какой-то момент будет недостаточно, StringBuilder создаст новый массив с вдвое большим размером и скопирует все символы там. Таким образом, это ограничивает количество раз, когда нам нужно изменить размер массива и перебрать все символы.

Так правильное решение будет выглядеть так:

StringBuilder sb = new StringBuilder(); 
for (String newPart : otherStrings){ 
    sb.append(newPart); 
    sb.append(", "); 
    //you could also chain these methods 
    //sb.append(newPart).append(", "); 
} 
String result = sb.toString(); 

BTW StringBuilder позволяет манипулировать на проводимых символов. Мы можем, например, удалить некоторые из своих символов через StringBuilder.delete(int start, int end).

0

Прямой переход от струнного конкатенации с помощью StringBuilder:

private String generateSuffix(List<String[]> searches, List<String[]> sorts) { 
    StringBuilder ret = new StringBuilder(); 
    if (searches != null && !searches.isEmpty()) { 
     ret.append("where "); 
     for (String[] search : searches) { 
      if (search.length < 3) { 
       continue; 
      } 
      ret.append(search[0]).append(search[1]).append(search[2]).append(" and "); 
     } 
     ret.delete(ret.length() - 5, ret.length()); 
    } 

    ret.append(" order by "); 
    if (sorts != null && !sorts.isEmpty()) { 
     for (String[] sort : sorts) { 
      if (sort.length < 2) { 
       continue; 
      } 
      ret.append(sort[0]).append(" ").append(sort[1]).append(","); 
     } 
    } 
    return ret.toString(); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^