title: Efficiently append last chars to StringBuilder
body: <p>Note: This question is about Java >= 9 which introduced <a href="https://openjdk.java.net/jeps/254" rel="nofollow noreferrer">"compact strings"</a></p>
  
  <hr>
  
  <p>Let's say I am appending an unknown number of strings (or chars) to a <code>StringBuilder</code> and at some point determine that I am appending the last string.</p>
  
  <p>How can this be done efficiently?</p>
  
  <h3>Background</h3>
  
  <p>If the capacity of the string builder is not large enough it will always increase it to <code>max(oldCap + str.lenght(), oldCap * 2 + 2)</code>. So if you are unlucky and the capacity is not enough for the last string, it will unnecessarily double the capcity, e.g.:</p>
  
  <pre><code>StringBuilder sb = new StringBuilder(4000);
  sb.append("aaa..."); // 4000 * "a"
  // Last string:
  sb.append("b"); // Unnecessarily increases capacity from 4000 to 8002
  return sb.toString();
  </code></pre>
  
  <p><code>StringBuilder</code> offers the methods <code>capacity()</code>, <code>length()</code> and <code>getChars(...)</code>, however manually creating a <code>char[]</code> and then creating a string will be inefficient because:</p>
  
  <ul>
  <li>Due to "compact strings" the string builder has to convert its bytes to chars</li>
  <li>When calling one of the <code>String</code> constructors the chars have to be compacted to bytes again</li>
  </ul>
  
  <p>Another option would be to check <code>capacity()</code> and if necessary create a <code>new StringBuilder(sb.length() + str.length())</code>, then append <code>sb</code> and <code>str</code>:</p>
  
  <pre><code>StringBuilder sb = new StringBuilder(4000);
  sb.append("aaa..."); // 4000 * "a"
  
  String str = "b";
  if (sb.capacity() - sb.length() &lt; str.length()) {
      return new StringBuilder(sb.length() + str.length())
          .append(sb)
          .append(str)
          .toString();
  }
  else {
      return sb.append(str).toString();
  }
  </code></pre>
  
  <p>The only disadvantage is that if the existing string builder or the new string is non-Latin 1 (2 bytes per char), the newly created string builder has to be "inflated" from 1 byte per char (Latin 1) to 2 bytes per char.</p>