2525/**
2626 * The format specification of a CSV file.
2727 *
28- * This class is thread-safe .
28+ * This class is immutable .
2929 */
30- public class CSVFormat implements Cloneable , Serializable {
30+ public class CSVFormat implements Serializable {
3131
32- private volatile char delimiter = ',' ;
33- private volatile char encapsulator = '"' ;
34- private volatile char commentStart = DISABLED ;
35- private volatile char escape = DISABLED ;
36- private volatile boolean leadingSpacesIgnored = true ;
37- private volatile boolean trailingSpacesIgnored = true ;
38- private volatile boolean unicodeEscapesInterpreted = false ;
39- private volatile boolean emptyLinesIgnored = true ;
40- private volatile String lineSeparator = " \r \n " ;
32+ private final char delimiter ;
33+ private final char encapsulator ;
34+ private final char commentStart ;
35+ private final char escape ;
36+ private final boolean leadingSpacesIgnored ;
37+ private final boolean trailingSpacesIgnored ;
38+ private final boolean unicodeEscapesInterpreted ;
39+ private final boolean emptyLinesIgnored ;
40+ private final String lineSeparator ;
4141
4242
4343 /**
@@ -49,7 +49,7 @@ public class CSVFormat implements Cloneable, Serializable {
4949 static final char DISABLED = '\ufffe' ;
5050
5151 /** Standard comma separated format as defined by <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>. */
52- public static final CSVFormat DEFAULT = new CSVFormat (',' , '"' , DISABLED , DISABLED , true , true , false , true );
52+ public static final CSVFormat DEFAULT = new CSVFormat (',' , '"' , DISABLED , DISABLED , true , true , false , true , " \r \n " );
5353
5454 /**
5555 * Excel file format (using a comma as the value delimiter).
@@ -62,11 +62,11 @@ public class CSVFormat implements Cloneable, Serializable {
6262 *
6363 * <pre>CSVFormat fmt = CSVFormat.EXCEL.withDelimiter(';');</pre>
6464 */
65- public static final CSVFormat EXCEL = new CSVFormat (',' , '"' , DISABLED , DISABLED , false , false , false , false );
65+ public static final CSVFormat EXCEL = new CSVFormat (',' , '"' , DISABLED , DISABLED , false , false , false , false , " \r \n " );
6666
6767 /** Tabulation delimited format. */
68- public static final CSVFormat TDF = new CSVFormat ('\t' , '"' , DISABLED , DISABLED , true , true , false , true );
69-
68+ public static final CSVFormat TDF = new CSVFormat ('\t' , '"' , DISABLED , DISABLED , true , true , false , true , " \r \n " );
69+
7070 /**
7171 * Default MySQL format used by the <tt>SELECT INTO OUTFILE</tt> and
7272 * <tt>LOAD DATA INFILE</tt> operations. This is a tabulation delimited
@@ -75,25 +75,8 @@ public class CSVFormat implements Cloneable, Serializable {
7575 *
7676 * @see <a href="http://dev.mysql.com/doc/refman/5.1/en/load-data.html">http://dev.mysql.com/doc/refman/5.1/en/load-data.html</a>
7777 */
78- public static final CSVFormat MYSQL = new CSVFormat ('\t' , DISABLED , DISABLED , '\\' , false , false , false , false ).withLineSeparator ("\n " );
79-
80-
81- /**
82- * Creates a CSV format with the default parameters.
83- */
84- CSVFormat () {
85- }
78+ public static final CSVFormat MYSQL = new CSVFormat ('\t' , DISABLED , DISABLED , '\\' , false , false , false , false , "\n " );
8679
87- /**
88- * Creates a customized CSV format.
89- *
90- * @param delimiter the char used for value separation
91- * @param encapsulator the char used as value encapsulation marker
92- * @param commentStart the char used for comment identification
93- */
94- CSVFormat (char delimiter , char encapsulator , char commentStart ) {
95- this (delimiter , encapsulator , commentStart , DISABLED , true , true , false , true );
96- }
9780
9881 /**
9982 * Creates a customized CSV format.
@@ -115,7 +98,8 @@ public class CSVFormat implements Cloneable, Serializable {
11598 boolean leadingSpacesIgnored ,
11699 boolean trailingSpacesIgnored ,
117100 boolean unicodeEscapesInterpreted ,
118- boolean emptyLinesIgnored ) {
101+ boolean emptyLinesIgnored ,
102+ String lineSeparator ) {
119103 this .delimiter = delimiter ;
120104 this .encapsulator = encapsulator ;
121105 this .commentStart = commentStart ;
@@ -124,6 +108,7 @@ public class CSVFormat implements Cloneable, Serializable {
124108 this .trailingSpacesIgnored = trailingSpacesIgnored ;
125109 this .unicodeEscapesInterpreted = unicodeEscapesInterpreted ;
126110 this .emptyLinesIgnored = emptyLinesIgnored ;
111+ this .lineSeparator = lineSeparator ;
127112 }
128113
129114 /**
@@ -182,10 +167,8 @@ public CSVFormat withDelimiter(char delimiter) {
182167 if (isLineBreak (delimiter )) {
183168 throw new IllegalArgumentException ("The delimiter cannot be a line break" );
184169 }
185-
186- CSVFormat format = clone ();
187- format .delimiter = delimiter ;
188- return format ;
170+
171+ return new CSVFormat (delimiter , encapsulator , commentStart , escape , leadingSpacesIgnored , trailingSpacesIgnored , unicodeEscapesInterpreted , emptyLinesIgnored , lineSeparator );
189172 }
190173
191174 /**
@@ -209,9 +192,7 @@ public CSVFormat withEncapsulator(char encapsulator) {
209192 throw new IllegalArgumentException ("The encapsulator cannot be a line break" );
210193 }
211194
212- CSVFormat format = clone ();
213- format .encapsulator = encapsulator ;
214- return format ;
195+ return new CSVFormat (delimiter , encapsulator , commentStart , escape , leadingSpacesIgnored , trailingSpacesIgnored , unicodeEscapesInterpreted , emptyLinesIgnored , lineSeparator );
215196 }
216197
217198 boolean isEncapsulating () {
@@ -239,9 +220,7 @@ public CSVFormat withCommentStart(char commentStart) {
239220 throw new IllegalArgumentException ("The comment start character cannot be a line break" );
240221 }
241222
242- CSVFormat format = clone ();
243- format .commentStart = commentStart ;
244- return format ;
223+ return new CSVFormat (delimiter , encapsulator , commentStart , escape , leadingSpacesIgnored , trailingSpacesIgnored , unicodeEscapesInterpreted , emptyLinesIgnored , lineSeparator );
245224 }
246225
247226 /**
@@ -274,9 +253,7 @@ public CSVFormat withEscape(char escape) {
274253 throw new IllegalArgumentException ("The escape character cannot be a line break" );
275254 }
276255
277- CSVFormat format = clone ();
278- format .escape = escape ;
279- return format ;
256+ return new CSVFormat (delimiter , encapsulator , commentStart , escape , leadingSpacesIgnored , trailingSpacesIgnored , unicodeEscapesInterpreted , emptyLinesIgnored , lineSeparator );
280257 }
281258
282259 boolean isEscaping () {
@@ -300,9 +277,7 @@ public boolean isLeadingSpacesIgnored() {
300277 * @return A copy of this format with the specified left trimming behavior.
301278 */
302279 public CSVFormat withLeadingSpacesIgnored (boolean leadingSpacesIgnored ) {
303- CSVFormat format = clone ();
304- format .leadingSpacesIgnored = leadingSpacesIgnored ;
305- return format ;
280+ return new CSVFormat (delimiter , encapsulator , commentStart , escape , leadingSpacesIgnored , trailingSpacesIgnored , unicodeEscapesInterpreted , emptyLinesIgnored , lineSeparator );
306281 }
307282
308283 /**
@@ -322,9 +297,7 @@ public boolean isTrailingSpacesIgnored() {
322297 * @return A copy of this format with the specified right trimming behavior.
323298 */
324299 public CSVFormat withTrailingSpacesIgnored (boolean trailingSpacesIgnored ) {
325- CSVFormat format = clone ();
326- format .trailingSpacesIgnored = trailingSpacesIgnored ;
327- return format ;
300+ return new CSVFormat (delimiter , encapsulator , commentStart , escape , leadingSpacesIgnored , trailingSpacesIgnored , unicodeEscapesInterpreted , emptyLinesIgnored , lineSeparator );
328301 }
329302
330303 /**
@@ -335,10 +308,7 @@ public CSVFormat withTrailingSpacesIgnored(boolean trailingSpacesIgnored) {
335308 * @return A copy of this format with the specified trimming behavior.
336309 */
337310 public CSVFormat withSurroundingSpacesIgnored (boolean surroundingSpacesIgnored ) {
338- CSVFormat format = clone ();
339- format .leadingSpacesIgnored = surroundingSpacesIgnored ;
340- format .trailingSpacesIgnored = surroundingSpacesIgnored ;
341- return format ;
311+ return new CSVFormat (delimiter , encapsulator , commentStart , escape , surroundingSpacesIgnored , surroundingSpacesIgnored , unicodeEscapesInterpreted , emptyLinesIgnored , lineSeparator );
342312 }
343313
344314 /**
@@ -358,9 +328,7 @@ public boolean isUnicodeEscapesInterpreted() {
358328 * @return A copy of this format with the specified unicode escaping behavior.
359329 */
360330 public CSVFormat withUnicodeEscapesInterpreted (boolean unicodeEscapesInterpreted ) {
361- CSVFormat format = clone ();
362- format .unicodeEscapesInterpreted = unicodeEscapesInterpreted ;
363- return format ;
331+ return new CSVFormat (delimiter , encapsulator , commentStart , escape , leadingSpacesIgnored , trailingSpacesIgnored , unicodeEscapesInterpreted , emptyLinesIgnored , lineSeparator );
364332 }
365333
366334 /**
@@ -380,9 +348,7 @@ public boolean isEmptyLinesIgnored() {
380348 * @return A copy of this format with the specified empty line skipping behavior.
381349 */
382350 public CSVFormat withEmptyLinesIgnored (boolean emptyLinesIgnored ) {
383- CSVFormat format = clone ();
384- format .emptyLinesIgnored = emptyLinesIgnored ;
385- return format ;
351+ return new CSVFormat (delimiter , encapsulator , commentStart , escape , leadingSpacesIgnored , trailingSpacesIgnored , unicodeEscapesInterpreted , emptyLinesIgnored , lineSeparator );
386352 }
387353
388354 /**
@@ -401,9 +367,7 @@ public String getLineSeparator() {
401367 * @return A copy of this format using the specified line separator
402368 */
403369 public CSVFormat withLineSeparator (String lineSeparator ) {
404- CSVFormat format = clone ();
405- format .lineSeparator = lineSeparator ;
406- return format ;
370+ return new CSVFormat (delimiter , encapsulator , commentStart , escape , leadingSpacesIgnored , trailingSpacesIgnored , unicodeEscapesInterpreted , emptyLinesIgnored , lineSeparator );
407371 }
408372
409373 /**
@@ -430,13 +394,4 @@ public String format(String... values) {
430394
431395 return out .toString ().trim ();
432396 }
433-
434- @ Override
435- protected CSVFormat clone () {
436- try {
437- return (CSVFormat ) super .clone ();
438- } catch (CloneNotSupportedException e ) {
439- throw (Error ) new InternalError ().initCause (e );
440- }
441- }
442397}
0 commit comments