diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 2ade95888..2c2bea9e1 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -22,6 +22,7 @@
+ Avoid String allocation in StrBuilder.append(CharSequence)
Update maven-checkstyle-plugin to 2.14
Update org.easymock:easymock to 3.3.1
Update maven-pmd-plugin to 3.4
diff --git a/src/main/java/org/apache/commons/lang3/text/StrBuilder.java b/src/main/java/org/apache/commons/lang3/text/StrBuilder.java
index 23e40d6fb..103b04035 100644
--- a/src/main/java/org/apache/commons/lang3/text/StrBuilder.java
+++ b/src/main/java/org/apache/commons/lang3/text/StrBuilder.java
@@ -505,7 +505,10 @@ public class StrBuilder implements CharSequence, Appendable, Serializable, Build
public StrBuilder append(final Object obj) {
if (obj == null) {
return appendNull();
- }
+ }
+ if (obj instanceof CharSequence) {
+ return append((CharSequence) obj);
+ }
return append(obj.toString());
}
@@ -521,7 +524,19 @@ public class StrBuilder implements CharSequence, Appendable, Serializable, Build
public StrBuilder append(final CharSequence seq) {
if (seq == null) {
return appendNull();
- }
+ }
+ if (seq instanceof StrBuilder) {
+ return append((StrBuilder) seq);
+ }
+ if (seq instanceof StringBuilder) {
+ return append((StringBuilder) seq);
+ }
+ if (seq instanceof StringBuffer) {
+ return append((StringBuffer) seq);
+ }
+ if (seq instanceof CharBuffer) {
+ return append((CharBuffer) seq);
+ }
return append(seq.toString());
}
@@ -606,6 +621,62 @@ public class StrBuilder implements CharSequence, Appendable, Serializable, Build
return append(String.format(format, objs));
}
+ /**
+ * Appends the contents of a char buffer to this string builder.
+ * Appending null will call {@link #appendNull()}.
+ *
+ * @param buf the char buffer to append
+ * @return this, to enable chaining
+ * @since 3.4
+ */
+ public StrBuilder append(final CharBuffer buf) {
+ if (buf == null) {
+ return appendNull();
+ }
+ if (buf.hasArray()) {
+ final int length = buf.remaining();
+ final int len = length();
+ ensureCapacity(len + length);
+ System.arraycopy(buf.array(), buf.arrayOffset() + buf.position(), buffer, len, length);
+ size += length;
+ } else {
+ append(buf.toString());
+ }
+ return this;
+ }
+
+ /**
+ * Appends the contents of a char buffer to this string builder.
+ * Appending null will call {@link #appendNull()}.
+ *
+ * @param buf the char buffer to append
+ * @param startIndex the start index, inclusive, must be valid
+ * @param length the length to append, must be valid
+ * @return this, to enable chaining
+ * @since 3.4
+ */
+ public StrBuilder append(final CharBuffer buf, final int startIndex, final int length) {
+ if (buf == null) {
+ return appendNull();
+ }
+ if (buf.hasArray()) {
+ final int totalLength = buf.remaining();
+ if (startIndex < 0 || startIndex > totalLength) {
+ throw new StringIndexOutOfBoundsException("startIndex must be valid");
+ }
+ if (length < 0 || (startIndex + length) > totalLength) {
+ throw new StringIndexOutOfBoundsException("length must be valid");
+ }
+ final int len = length();
+ ensureCapacity(len + length);
+ System.arraycopy(buf.array(), buf.arrayOffset() + buf.position() + startIndex, buffer, len, length);
+ size += length;
+ } else {
+ append(buf.toString(), startIndex, length);
+ }
+ return this;
+ }
+
/**
* Appends a string buffer to this string builder.
* Appending null will call {@link #appendNull()}.
diff --git a/src/test/java/org/apache/commons/lang3/text/StrBuilderTest.java b/src/test/java/org/apache/commons/lang3/text/StrBuilderTest.java
index ec959aff9..2da4cf1ef 100644
--- a/src/test/java/org/apache/commons/lang3/text/StrBuilderTest.java
+++ b/src/test/java/org/apache/commons/lang3/text/StrBuilderTest.java
@@ -1938,6 +1938,21 @@ public class StrBuilderTest {
assertEquals(sb.toString(), sb.build());
}
+ //-----------------------------------------------------------------------
+ @Test
+ public void testAppendCharBuffer() {
+ final StrBuilder sb1 = new StrBuilder();
+ final CharBuffer buf = CharBuffer.allocate(10);
+ buf.append("0123456789");
+ buf.flip();
+ sb1.append(buf);
+ assertEquals("0123456789", sb1.toString());
+
+ final StrBuilder sb2 = new StrBuilder();
+ sb2.append(buf, 1, 8);
+ assertEquals("12345678", sb2.toString());
+ }
+
//-----------------------------------------------------------------------
@Test
public void testAppendToWriter() throws Exception {