diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 722ed206..ce9a959a 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -38,6 +38,9 @@
Release Notes
+
+ Make CSVPrinter.print(Object) GC-free.
+
Add shortcut method for using first record as header to CSVFormat
Add withHeader(Class<? extends Enum>) to CSVFormat
diff --git a/src/main/java/org/apache/commons/csv/CSVPrinter.java b/src/main/java/org/apache/commons/csv/CSVPrinter.java
index dc23e1b9..cdd2c11e 100644
--- a/src/main/java/org/apache/commons/csv/CSVPrinter.java
+++ b/src/main/java/org/apache/commons/csv/CSVPrinter.java
@@ -121,15 +121,33 @@ public final class CSVPrinter implements Flushable, Closeable {
*/
public void print(final Object value) throws IOException {
// null values are considered empty
- String strValue;
+ // Only call CharSequence.toString() if you have to, helps GC-free use cases.
+ CharSequence charSequence;
if (value == null) {
final String nullString = format.getNullString();
- strValue = nullString == null ? Constants.EMPTY : nullString;
+ charSequence = nullString == null ? Constants.EMPTY : nullString;
} else {
- strValue = value.toString();
+ charSequence = value instanceof CharSequence ? (CharSequence) value : value.toString();
}
- strValue = format.getTrim() ? strValue.trim() : strValue;
- this.print(value, strValue, 0, strValue.length());
+ charSequence = format.getTrim() ? trim(charSequence) : charSequence;
+ this.print(value, charSequence, 0, charSequence.length());
+ }
+
+ private CharSequence trim(final CharSequence charSequence) {
+ if (charSequence instanceof String) {
+ return ((String) charSequence).trim();
+ }
+ final int count = charSequence.length();
+ int len = count;
+ int pos = 0;
+
+ while ((pos < len) && (charSequence.charAt(pos) <= ' ')) {
+ pos++;
+ }
+ while ((pos < len) && (charSequence.charAt(len - 1) <= ' ')) {
+ len--;
+ }
+ return (pos > 0) || (len < count) ? charSequence.subSequence(pos, len) : charSequence;
}
private void print(final Object object, final CharSequence value, final int offset, final int len)