Summary
Add the ability to repeatedly append char
/code point and CharSequence
data to StringBuilder/StringBuffer
.
Problem
Appending a repeated sequence of characters to a StringBuilder
is more complicated and inefficient than necessarily.
Typically, a cumbersome counting loop is required to repeatedly append a sequence.
Example: Text justification with loop
static String rightJustify(String str, int width) { int padding = Math.max(0, width - str.length()); StringBuilder sb = new StringBuilder(width); for (int i = 0; i < padding; i++) { sb.append(' '); } return sb.append(str).toString(); }
String::repeat
has been available since JDK 11. Unfortunately use of String::repeat
requires the allocation of an intermediary String
.
Example: Text justification with String::repeat
static String rightJustify(String str, int width) { int padding = Math.max(0, width - str.length()); return new StringBuilder(width) .append(" ".repeat(padding)); .append(str) .toString(); }
Solution
The proposed solution is to add two methods to the StringBuilder
and StringBuffer
classes;
repeat(int codePoint, int count)
and repeat(CharSequence cs, int count)
.
Example: Text justification with StringBuilder::repeat
static String rightJustify(String str, int width) { int padding = Math.max(0, width - str.length() ; return new StringBuilder(width) .repeat(' ', padding); .append(str); .toString(); }
The additional benefit is that replication occurs directly in the StringBuilder
buffer without any intermediary objects.
loopRepeatChar thrpt 25 46507857.247 ± 16001.611 ops/s for (int i = 0; i < 10; i++) sb.append('*');
loopRepeatString thrpt 25 43482336.436 ± 177227.305 ops/s for (int i = 0; i < 10; i++) sb.append("+-");
loopRepeatStringUTF16 thrpt 25 40556583.647 ± 365770.314 ops/s for (int i = 0; i < 10; i++) sb.append("\u2022-");
strRepeatChar thrpt 25 209038459.568 ± 125055.304 ops/s sb.append("*".repeat(10));
strRepeatString thrpt 25 67675968.232 ± 509906.866 ops/s sb.append("+-".repeat(10));
strRepeatStringUTF16 thrpt 25 71712982.352 ± 40114.633 ops/s sb.append("\u2022-".repeat(10));
sbRepeatChar thrpt 25 295722073.244 ± 277205.579 ops/s sb.repeat('*', 10);
sbRepeatString thrpt 25 76166442.540 ± 3213215.843 ops/s sb.repeat("+-", 10);
sbRepeatStringUTF16 thrpt 25 82658897.156 ± 3971140.701 ops/s sb.repeat("\u2022-", 10);
sbRepeatStringOneChar thrpt 25 286870925.029 ± 13221451.039 ops/s sb.repeat("*", 10);
Specification
For StringBuilder:
/**
* Repeats {@code count} copies of the string representation of the
* {@code codePoint} argument to this sequence.
* <p>
* The length of this sequence increases by {@code count} times the
* string representation length.
* <p>
* It is usual to use {@code char} expressions for code points. For example:
* {@snippet lang="java":
* // insert 10 asterisks into the buffer
* sb.repeat('*', 10);
* }
*
* @param codePoint code point to append
* @param count number of times to copy
*
* @return a reference to this object.
*
* @throws IllegalArgumentException if the specified {@code codePoint}
* is not a valid Unicode code point or if {@code count} is negative.
*
* @since 21
*/
public StringBuilder repeat(int codePoint, int count) {
/**
* Appends {@code count} copies of the specified {@code CharSequence} {@code cs}
* to this sequence.
* <p>
* The length of this sequence increases by {@code count} times the
* {@code CharSequence} length.
* <p>
* If {@code cs} is {@code null}, then the four characters
* {@code "null"} are repeated into this sequence.
*
* @param cs a {@code CharSequence}
* @param count number of times to copy
*
* @return a reference to this object.
*
* @throws IllegalArgumentException if {@code count} is negative
*
* @since 21
*/
public StringBuilder repeat(CharSequence cs, int count) {
For StringBuffer:
/**
* Repeats {@code count} copies of the string representation of the
* {@code codePoint} argument to this sequence.
* <p>
* The length of this sequence increases by {@code count} times the
* string representation length.
* <p>
* It is usual to use {@code char} expressions for code points. For example:
* {@snippet lang="java":
* // insert 10 asterisks into the buffer
* sb.repeat('*', 10);
* }
*
* @param codePoint code point to append
* @param count number of times to copy
*
* @return a reference to this object.
*
* @throws IllegalArgumentException if the specified {@code codePoint}
* is not a valid Unicode code point or if {@code count} is negative.
*
* @since 21
*/
public synchronize StringBuffer repeat(int codePoint, int count) {
/**
* Appends {@code count} copies of the specified {@code CharSequence} {@code cs}
* to this sequence.
* <p>
* The length of this sequence increases by {@code count} times the
* {@code CharSequence} length.
* <p>
* If {@code cs} is {@code null}, then the four characters
* {@code "null"} are repeated into this sequence.
*
* @param cs a {@code CharSequence}
* @param count number of times to copy
*
* @return a reference to this object.
*
* @throws IllegalArgumentException if {@code count} is negative
*
* @since 21
*/
public synchronize StringBuffer repeat(CharSequence cs, int count) {
- csr of
-
JDK-8302323 Add repeat methods to StringBuilder/StringBuffer
- Resolved